MyBatis-Plus 源码阅读(二):只引入一个 Starter,启动时发生了什么
MyBatis-Plus 源码阅读(二):只引入一个 Starter,启动时发生了什么
平时接入 MyBatis-Plus,大多只加一个 Starter,再写个 @MapperScan。
业务代码里没有手动创建 SqlSessionFactory,也没有注册 BaseMapper。这些东西从哪里来的?
答案在 MybatisPlusAutoConfiguration。
自动配置什么时候生效
先看类上的几个条件:
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisPlusProperties.class)
public class MybatisPlusAutoConfiguration {
}
翻成人话就是:
- classpath 里得有 MyBatis 和 MyBatis-Spring;
- Spring 容器里得有一个明确的数据源;
mybatis-plus.*配置会绑定到MybatisPlusProperties;- 条件满足后,这个自动配置类才开始干活。
如果项目里有多个 DataSource,又没有标明哪个是主要候选者,这段自动配置可能根本不会生效。这类问题只看 Mapper 报错,往往找不到原因。
最重要的 Bean:SqlSessionFactory
sqlSessionFactory(DataSource) 是这篇的主入口。
它没有使用 MyBatis-Spring 原生的 SqlSessionFactoryBean,而是创建:
MybatisSqlSessionFactoryBean factory =
new MybatisSqlSessionFactoryBean();
接着往工厂里放入数据源、MybatisConfiguration、Mapper XML 地址、插件、TypeHandler、LanguageDriver 和 GlobalConfig。
我们自己声明的几个 Bean,也是在这里被接走的:
MetaObjectHandler
AnnotationHandler
PostInitTableInfoHandler
IKeyGenerator
ISqlInjector
IdentifierGenerator
例如项目中放一个 MetaObjectHandler Bean,不需要再手动塞进 MyBatis。自动配置会找到它,再放入 GlobalConfig。
MybatisConfiguration 从哪来
applyConfiguration() 会根据配置文件情况决定 Configuration 的来源。
没有指定原生 MyBatis 配置文件时,默认创建:
new MybatisConfiguration()
它继承 MyBatis 的 Configuration,但增强了几处关键行为:
- 使用
MybatisMapperRegistry; - 默认开启下划线转驼峰;
- 默认使用组合枚举 TypeHandler;
- 默认使用
MybatisXMLLanguageDriver; - 调整同名
MappedStatement的处理方式。
MyBatis-Plus 没有丢掉 MyBatis Configuration,只是在它上面换了几个自己需要的零件。
FactoryBean 真正构建了什么
MybatisSqlSessionFactoryBean.buildSqlSessionFactory() 的顺序可以缩成:
确定 Configuration
-> 绑定 GlobalConfig
-> 注册别名、插件、TypeHandler、LanguageDriver
-> 创建 Environment
-> 解析 Mapper XML
-> MybatisSqlSessionFactoryBuilder.build()
-> 得到 SqlSessionFactory
Environment 把数据源和事务工厂交给 MyBatis。在 Spring 环境里,默认使用 SpringManagedTransactionFactory,事务仍由 Spring 管。
Mapper 是怎么被扫进来的
这里有两种情况。
项目显式写了:
@MapperScan("com.example.mapper")
那么 MyBatis-Spring 的扫描器负责注册 Mapper。
如果没有 @MapperScan,也没有自己配置 MapperFactoryBean 或 MapperScannerConfigurer,自动配置中的 AutoConfiguredMapperScannerRegistrar 会兜底扫描。
但这个兜底扫描只找带 @Mapper 的接口:
// 有 @MapperScan 时,可以不写 @Mapper
public interface UserMapper extends BaseMapper<User> {
}
// 依赖自动配置兜底扫描时,需要 @Mapper
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
SqlSessionTemplate 又是什么
自动配置还会创建 SqlSessionTemplate。
它是 MyBatis-Spring 提供的线程安全 SqlSession 门面。Mapper 最终通过它参与 Spring 事务,并获取、释放真正的会话。
到这里,Spring 和 MyBatis 的连接就搭好了:
DataSource
-> MybatisSqlSessionFactoryBean
-> SqlSessionFactory
-> SqlSessionTemplate
-> MapperFactoryBean
-> Mapper 代理
怎么验证
在上一篇的 H2 项目里加一个测试:
@Autowired
private SqlSessionFactory sqlSessionFactory;
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
@Test
void shouldUseMybatisPlusConfiguration() {
Configuration configuration =
sqlSessionFactory.getConfiguration();
assertInstanceOf(
MybatisConfiguration.class,
configuration
);
assertSame(
sqlSessionFactory,
sqlSessionTemplate.getSqlSessionFactory()
);
}
本文来自博客园,作者:01o00o10,转载请注明原文链接:https://www.cnblogs.com/01o00o10/articles/23050338

浙公网安备 33010602011771号