一、MapperScannerConfigurer接口实现了BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法。
postProcessBeanDefinitionRegistry调用时机是在spring容器refresh方法中调用。如图:
postProcessBeanDefinitionRegistry方法的作用是在创建bean之前添加或者修改beanDefinition,
二、MapperScannerConfigurer实现postProcessBeanDefinitionRegistry方法,主要作用是根据配置的basePackage属性找到mapper接口,
然后根据mapper接口的相关信息创建beanDefinition,并注册到beanFactory中。
1、具体逻辑在ClassPathMapperScanner.scan方法中,scan方法在postProcessBeanDefinitionRegistry方法的最后一行被调用,如图:
2、scan方法是ClassPathMapperScanner的父类方法,在scan实际调用的是doScan
3、ClassPathMapperScanner类重写了doScan方法,所以直接看ClassPathMapperScanner.doScan方法
4、上面框起来的两行代码
(1)第一个框调用父类ClassPathBeanDefinitionScanner的doScan方法
是根据basePackages包下的所有mapper接口new一个beanDefinition实例,
然后给这些beanDefinition设置一些的默认属性,并把这些beanDefinition注册到beanFactory。
(2)第二个框调用processBeanDefinitions方法,对(1)中父类doScan方法创建的beanDefinition再进行处理,补充设置一些默认属性
这里设置的属性很多,像autowireMode、scope、lazyInit等等,不过最关键的应该是修改了beanClass属性。
在(1)中返回的beanDefinition的beanClass属性还是mapper接口的全限定名,然后在这里都设置为MapperFactoryBean.Class
5、这个时候各个mapper的beanDefinition的信息就比较完整了,后续就是spring的getBean根据beanDefinition创建bean的流程了。
6、别忘了,beanDefinition的beanClass是MapperFactoryBean.Class,当getBean获取mapper实例或者注入mapper的时候,
实际上是通过MapperFactoryBean.getObject创建和获取真正的mapper实例。