浅聊Mybatis是怎么扫描并且注入到spring容器中的(源码向)
- 源码很枯燥,但是能学到很多东西,废话不多说直接进入正题:
@MapperScan 扫描注入 spring beanDefinition 的流程
- 在使用注解确认扫包范围的时候
- 注解里的@Import(MapperScannerRegistrar.class)
- 引入了 MapperScannerRegistrar 这个类,然后引入了MapperScannerConfigurer 这个类。进行的扫描
- 因为该类实现了 ImportBeanDefinitionRegistrar
- 在SpringBoot启动的时候 以下是完整的 spring 到 mybatis scan 的完整流程. 有兴趣的朋友可以ctrl + N 跟着看看数据
- 1.初始化环境: AbstractApplicationContext#refresh ->
- 2.激活各种BeanFactory处理器: invokeBeanFactoryPostProcessors ->
- 3.循环扫描bean定义:PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors ->
- 4.调用bean定义注册处理器:PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors ->
- 5.bean定义注册处理器:(许多框架都是实现此处进行指定bean的定义注入)BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry ->
- 6.spring第一次会加载 (完成一些主要的扫描): ConfigurationClassPostProcessor ->
- 7.加载扫描到的bean定义: this.reader.loadBeanDefinitions(configClasses) ->
- 8.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsFromRegistrars ->
- 9.ImportBeanDefinitionRegistrar#registerBeanDefinitions ->
- 10.注册bean定义:(将 MapperScannerConfigurer 加载入bean容器中) MapperScannerRegistrar#registerBeanDefinitions ->
- 11.然后callBack到3->4->5: MapperScannerConfigurer#postProcessBeanDefinitionRegistry ->
- 11.进行mybatis的扫描: ClassPathMapperScanner#doScan ->
- 12.将所有符合扫描条件的类都注册到bean中,设置 MapperFactoryBean 作为 FactoryBean: ClassPathMapperScanner#processBeanDefinitions
简要说一下 Mapper 的加载流程
- 上述流程中。就是 @MapperScan 注解。使得符合条件的类都 以 FactoryBean 的定义注入到了 beanDefinition 中
- 那么 doGetBean 的流程是这样:
-
- bean启动流程中 会先加载实现了 InitializingBean的方法 : MapperFactoryBean extends SqlSessionDaoSupport extends DaoSupport implements InitializingBean ->
-
- 由于继承关系,会初始化方法: MapperFactoryBean#checkDaoConfig ->
-
- 调用: Configuration#addMapper ->
-
- 调用: MapperRegistry#addMapper ->
-
- 分析xml数据: MapperAnnotationBuilder#parse ->
-
- 解析并添加MappedStatement (提供给调用mapper方法的时候使用): MapperAnnotationBuilder#addMappedStatement ->