springboot中,mybatis的mapper接口是如何生成代理对象的?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot中,mybatis的mapper接口是如何生成代理对象的?相关的知识,希望对你有一定的参考价值。

参考技术A 引入了以下包

其中自动装配的包就是mybatis-spring-boot-autoconfigure。

META-INF下有一个spring.factories文件

导入了这个类MybatisAutoConfiguration

注册MapperScannerConfigurer的Bean定义到Spring容器中,并设置扫描包的路径

MapperScannerConfigurer 实现BeanDefinitionRegistryPostProcessor接口,实例化的时候会调到postProcessBeanDefinitionRegistry方法,这个方法里会创建一个ClassPathMapperScanner对象,然后去扫描

扫描到之后修改BeanDefinition

@MapperScan注解,会import进来MapperScannerRegistrar这个类

MapperScannerRegistrar类实现ImportBeanDefinitionRegistrar接口,实例化的时候会调用registerBeanDefinitions方法

和@Mapper一样,同样会创建MapperScannerConfigurer的BeanDefition,用于后续实例化

只不过要扫描的包路径变了,不再是默认的,而是@MapperScan配置的包路径

后面的话则和@Mapper扫描到之后的工作原理是一样的,扫描到之后,更改BeanDefinition,一毛一样的。

==可以看出@MapperScan最主要的工作原理除了提供BasePackage的值之外,就是用@Import注解导入MapperScannerRegistrar.所以这个注解打在任何可以被spring扫描到的类上都可以,并不一定要打在启动类上(大多数为了只是为了看起来方便,把全局性的配置注解打在启动类上而已)==

前面提到,注册扫描@Mapper接口的MapperScannerConfigurer实例的类是AutoConfiguredMapperScannerRegistrar,那么这个类是如何被导入进来的呢

MybatisAutoConfiguration还有一个静态内部类,@Import了AutoConfiguredMapperScannerRegistrar类,但是有@ConditionalOnMissingBean,即spring容器中不存在MapperFactoryBean,MapperScannerConfigurer的实例。

如果@MapperScan注解生效,并且扫描到任意一个Mapper接口(前面被改造成MapperFactoryBean类型的了),那么就不满足注册这个类MapperScannerRegistrarNotFoundConfiguration的实例的条件,继而不会导入AutoConfiguredMapperScannerRegistrar类。

前面提到,所有的Mapper接口被扫描到,封装成BeanDefinition,还经历了一次改造,

最主要的就是将mapper接口BeanDefination的beanClass改成了org.mybatis.spring.mapper.MapperFactoryBean.class
并且将mapper接口BeanDefination的名称作为构造函数的入参传入进去

并讲BeanDefinition的autowireMode属性改成 AUTOWIRE_BY_TYPE ,后面实例化该bean的时候会调用属性的描述器,用write的方式注入属性值,最重要的那个属性那就是SqlSessionTemplate. 会通过这种方式将前面MybatisAutoConfiguration中@Bean出来的SqlSessionTemplate注入到其中。

类图:

这里他实现了FactoryBean,
FactoryBean有以下方法

这里是spring的一个拓展点,实现了FactoryBean接口的类,将可以实现getObject() 和getObjectType来实例化额外的一个bean并装到spring容器中

好吧,其实Mapper代理对象的创建就是在MapperFactoryBean的getObject方法中返回的

这里就是熟悉的原生Mybatis创建Mapper接口的味道了。

附上调用的类时序图,回过头来看一下调用的整体流程。

以上是关于springboot中,mybatis的mapper接口是如何生成代理对象的?的主要内容,如果未能解决你的问题,请参考以下文章

怎么创建SpringBoot项目并实现数据库的增删改查

mybatis_个人总结

MyBatis

Mybatis的parameterType传入多个参数

Mybatis基本的CRUD

MyBaties--Mapper configuration