深入理解Mybatis-Spring工作原理

简介: 深入理解Mybatis-Spring工作原理

Mybatis-Spring做了什么?

MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。 使用这个类库中的类, Spring 将会加载必要的 MyBatis 工厂类和 session 类。 这个类库也提供一个简单的方式来注入 MyBatis 数据映射器和 SqlSession 到业务层的 bean 中。

Mybatis-Spring如何做到?

Mybatis需要首先扫描到所有的Mybatis的Mapper类,然后将通过session获取该Mapper对应的实例。然后Spring就可以将Mybatis的Mapper实例注入到Service中

使用了。

首先从配置入口来看

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  <property name="basePackage" value="" />
</bean>

入口类为MapperScannerConfigurer, 该类实现了BeanDefinitionRegistryPostProcessor接口用来查找Mapper类,然后将MapperFactoryBean设置为Mapper的

实现类。MapperFactoryBean是一个代理类,会根据Mapper信息通过sqlSession获取对应Mapper的实例。以上就是Mybatis-Spring的所有任务。

MapperScannerConfigurer如何查找Mapper

了解Mapper查找的原理,首先要了解BeanDefinitionRegistryPostProcessor接口。开发人员通过 XML 文件或者 Annotation 预定义配置 bean 的各种属性后,启动 Spring 容器,Spring 容器会首先解析这些配置属性,生成对应都 Bean Definition,装入到 DefaultListableBeanFactory 对象的属性容器中去。Spring 框架会根据配置,过滤出 BeanDefinitionRegistryPostProcessor 类型的 Bean 定义,并通过 Spring 框架生成其对应的 Bean 对象。Spring 容器会在实例化开发人员所定义的 Bean 前先调用该 processor 的 postProcessBeanDefinitionRegistry(…) 方法。此处可以操作和配置Bean Definition。下面是MapperScannerConfigurer的源码

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
   if (this.processPropertyPlaceHolders) {
     processPropertyPlaceHolders();
   }
//配置需要查找的Mapper类的信息
   ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
   scanner.setAddToConfig(this.addToConfig);
   scanner.setAnnotationClass(this.annotationClass);
   scanner.setMarkerInterface(this.markerInterface);
   scanner.setSqlSessionFactory(this.sqlSessionFactory);
   scanner.setSqlSessionTemplate(this.sqlSessionTemplate);
   scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);
   scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);
   scanner.setResourceLoader(this.applicationContext);
   scanner.setBeanNameGenerator(this.nameGenerator);
   scanner.registerFilters();
   scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
 }

ClassPathMapperScanner继承了ClassPathBeanDefinitionScanner,scanner.scan()语句会调用ClassPathMapperScanner的doScan函数。然后此函数中将MapperFactoryBean设置为查找到的Mapper的实现类

public Set<BeanDefinitionHolder> doScan(String... basePackages) {
   Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
   if (beanDefinitions.isEmpty()) {
     logger.warn("No MyBatis mapper was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration.");
   } else {
  //遍历找到的Mapper
     for (BeanDefinitionHolder holder : beanDefinitions) {
       GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();
       //下面的definition.getPropertyValues().add函数均为实例化代理类设置参数,以使得MapperFactoryBean完成代理
       definition.getPropertyValues().add("mapperInterface", definition.getBeanClassName());
  // 设置Mapper的实现类为MapperFactoryBean
       definition.setBeanClass(MapperFactoryBean.class);
       definition.getPropertyValues().add("addToConfig", this.addToConfig);
       boolean explicitFactoryUsed = false;
       if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) {
         definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName));
         explicitFactoryUsed = true;
       } else if (this.sqlSessionFactory != null) {
         definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory);
         explicitFactoryUsed = true;
       }
       if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) {
         definition.getPropertyValues().add("sqlSessionTemplate", new RuntimeBeanReference(this.sqlSessionTemplateBeanName));
         explicitFactoryUsed = true;
       } else if (this.sqlSessionTemplate != null) {
         definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate);
         explicitFactoryUsed = true;
       }
       if (!explicitFactoryUsed) {
         definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
       }
     }
   }
   return beanDefinitions;
 }

然后就是MapperFactoryBean根据实例化的信息创建对应的Mapper实例了

public T getObject() throws Exception {
  return getSqlSession().getMapper(this.mapperInterface);
}

就这样Mybatis-Spring省去了手工配置Mapper,帮助开发者实现自动的配置,使得开发快速。

Mybatis涉及的主要类

MapperScannerConfigurer – ClassPathMapperScanner – MapperFactoryBean

(完)

本文作者 : cyningsun

本文地址https://www.cyningsun.com/08-17-2014/reading-mybatis-spring-source-code.html

版权声明 :本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!


目录
相关文章
|
29天前
|
XML Java 开发者
Spring Boot开箱即用可插拔实现过程演练与原理剖析
【11月更文挑战第20天】Spring Boot是一个基于Spring框架的项目,其设计目的是简化Spring应用的初始搭建以及开发过程。Spring Boot通过提供约定优于配置的理念,减少了大量的XML配置和手动设置,使得开发者能够更专注于业务逻辑的实现。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,为开发者提供一个全面的理解。
29 0
|
4月前
|
安全 Java 数据库
一天十道Java面试题----第四天(线程池复用的原理------>spring事务的实现方式原理以及隔离级别)
这篇文章是关于Java面试题的笔记,涵盖了线程池复用原理、Spring框架基础、AOP和IOC概念、Bean生命周期和作用域、单例Bean的线程安全性、Spring中使用的设计模式、以及Spring事务的实现方式和隔离级别等知识点。
|
19小时前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
26 14
|
4月前
|
Java
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
这篇文章是Spring5框架的实战教程,深入讲解了AOP的基本概念、如何利用动态代理实现AOP,特别是通过JDK动态代理机制在不修改源代码的情况下为业务逻辑添加新功能,降低代码耦合度,并通过具体代码示例演示了JDK动态代理的实现过程。
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
|
29天前
|
SQL Java 数据库连接
Mybatis架构原理和机制,图文详解版,超详细!
MyBatis 是 Java 生态中非常著名的一款 ORM 框架,在一线互联网大厂中应用广泛,Mybatis已经成为了一个必会框架。本文详细解析了MyBatis的架构原理与机制,帮助读者全面提升对MyBatis的理解和应用能力。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Mybatis架构原理和机制,图文详解版,超详细!
|
22天前
|
Java 开发者 Spring
Spring AOP 底层原理技术分享
Spring AOP(面向切面编程)是Spring框架中一个强大的功能,它允许开发者在不修改业务逻辑代码的情况下,增加额外的功能,如日志记录、事务管理等。本文将深入探讨Spring AOP的底层原理,包括其核心概念、实现方式以及如何与Spring框架协同工作。
|
5月前
|
Java 应用服务中间件 开发者
Java面试题:解释Spring Boot的优势及其自动配置原理
Java面试题:解释Spring Boot的优势及其自动配置原理
126 0
|
5月前
|
设计模式 监控 Java
解析Spring Cloud中的断路器模式原理
解析Spring Cloud中的断路器模式原理
|
2月前
|
Java Spring 容器
Spring底层原理大致脉络
Spring底层原理大致脉络
|
2月前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
142 9