pom
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
在mybatis-spring-boot-autoconfigure这个jar的spring.factories中
MybatisAutoConfiguration这个类注入了SqlSessionFactory和SqlSessionTemplate
MybatisAutoConfiguration有一个内部类比较重要
不存在MapperFactoryBean这个bean会导入AutoConfiguredMapperScannerRegistrar,
什么情况会存在MapperFactoryBean,使用@MapperScan注解会存在
原因如下:
MapperScannerRegistrar的registerBeanDefinitions—》registerBeanDefinitions—》ClassPathMapperScanner的doScan—》processBeanDefinitions
processBeanDefinitions特别重要,此方法将@MapperScan注解需要扫描的包下的类的bean定义都变成MapperFactoryBean,如下图
MapperFactoryBean是做什么的呢?
spring在实例化mapper接口时,由于bean定义都被改为MapperFactoryBean,将会调用MapperFactoryBean的getObject方法,此方法中使用了SqlSessionTemplate(SqlSessionTemplate使用动态代理增强SqlSession),并使用动态代理创建了接口的代理类MapperProxy(实现InvocationHandler)
当不使用@MapperScan注解,即不存在MapperFactoryBean这个bean,MybatisAutoConfiguration会导入AutoConfiguredMapperScannerRegistrar,
此类的registerBeanDefinitions方法会扫描标注@Mapper注解的类,也是和上面@MapperScan一样,将bean定义修改
原理大概如此
简单了解下SqlSessionTemplate
上图的sqlSessionProxy即代理类,调用SqlSession的方法会调用SqlSessionInterceptor(实现了InvocationHandler),强调一点,SqlSessionInterceptor此类invoke调用的SqlSession的实例是从ThreadLocal里取出来的,有兴趣的可以翻看下源码,所以是线程安全的