Mybatis-spring-boot-starter的入口
会在springboot启动的时候加载autoconfigure模块定义的自动装配类:MybatisAutoConfiguration
MybatisAutoConfiguration中装配Mybatis的逻辑
SqlSessionFactory的构造
1 |
|
SqlSessionFactory的实例化是通过SqlSessionFactoryBean.getObject()实现的,该类会被注入DataSource对象(负责管理数据库连接池,Session指的是一次会话,而这个会话是在DataSource提供的Connection上进行的)。
在factory.getObject()中,最核心还是调用了buildSqlSessionFactory 去创建了sqlSessionFactory实例。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31protected SqlSessionFactory buildSqlSessionFactory() throws IOException {
Configuration configuration;
XMLConfigBuilder xmlConfigBuilder = null;
if (this.configLocation != null) {
// 创建XMLConfigBuilder对象,读取指定的配置文件
xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(),
null, this.configurationProperties);
configuration = xmlConfigBuilder.getConfiguration();
} else {
// 其他方式初始化Configuration全局配置对象
}
// 初始化MyBatis的相关配置和对象,其中包括:
// 扫描typeAliasesPackage配置指定的包,并为其中的类注册别名
// 注册plugins集合中指定的插件
// 扫描typeHandlersPackage指定的包,并注册其中的TypeHandler
// 配置缓存、配置数据源、设置Environment等一系列操作
// ...... 省略配置代码
if (this.transactionFactory == null) {
// 默认使用的事务工厂类
this.transactionFactory = new SpringManagedTransactionFactory();
}
// 根据mapperLocations配置,加载Mapper.xml映射配置文件以及对应的Mapper接口
for (Resource mapperLocation : this.mapperLocations) {
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(...);
xmlMapperBuilder.parse();
}
// 最后根据前面创建的Configuration全局配置对象创建SqlSessionFactory对象
return this.sqlSessionFactoryBuilder.build(configuration);
}
SqlSessionFactory.getObject()方法里会根据我们mybatis相关配置(比如上面的mybatis.mapper-locations配置)找到并解析我们的mapper文件,解析出sql与dao方法里的映射、ResultMap与具体实体类的映射等,并放到SqlSessionFactory的Configuration中缓存下来,在后续调用过程中会通过这些信息来匹配jdbc操作。这个过程中会生成Mapper的代理类,执行sql时会走代理拦截方法执行,则不需要实现类就可以直接调用到具体的sql。
SqlSessionTemplate
如果使用手写java代码的方式去操作数据库,则使用的为sqlSessionTemplate,SqlSessionTemplate 是线程安全的,可以在多个线程之间共享使用。SqlSessionTemplate 内部持有一个 SqlSession 的代理对象(sqlSessionProxy 字段),这个代理对象是通过 JDK 动态代理方式生成的;使用的 InvocationHandler 接口是 SqlSessionInterceptor,其 invoke() 方法会拦截 SqlSession 的全部方法,并检测当前事务是否由 Spring 管理。
在MybatisAutoConfiguration自动配置中也去生成了SqlSessionTemplate这个bean对象。
1 |
|
MapperFactoryBean和MapperScannerConfigurer
在MybatisAutoConfiguration中注册了AutoConfiguredMapperScannerRegistrar,其实ImportBeanDefinitionRegistrar的实现类,Spring中可以通过 @Import 注解导入的 ImportBeanDefinitionRegistrar 实现类往 BeanDefinitionRegistry 注册 BeanDefinition。这里其实就是去注册了MapperScannerConfigurer 这个BeanDefinitionRegistryPostProcessor的实现。
BeanDefinitionRegistryPostProcessor是一个特殊的接口,继承了BeanFactoryPostProcessor接口,提供了注册bean定义的能力,这里MapperScannerConfigurer扫描所有的@Mapper注解的Maapper类,在扩展点方法中去注册bean定义都为MapperFactoryBean接口,这些Bean在实例化时会因为是FactoryBean,而调用getObject方法寻找Mapper接口的动态代理缓存。
1 | public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { |
MapperFactoryBean的getObject()方法是从Configuration配置对象中寻找对应Mapper接口的代理类缓存,没有的话会创建。 这个SpringBean在注入的时候就是对应的代理类了。内部会转发到sqlSession、SqlExecutor去执行sql。
1 |
|