SqlSessionFactoryBean的构建流程
目的
此文的主旨在于梳理SqlSessionFactoryBean的初始流程,不拘泥于实现细节。
使用
SqlSessionFactoryBean
的主要作用便是用来创建SqlSessionFactory
,在它的构建过程中会解析MyBatis
所需要的配置文件,将所有配置都封装到Configuration
类中,最后返回SqlSessionFactory实例
。SqlSessionFactoryBean
实现了Spring
中两个用于初始化Bean的接口FactoryBean
、InitializingBean
.
InitializingBean定义如下
public interface InitializingBean {
/**
* 此方法在BeanFactory设置了Bean配置里的所有属性后执行。
*/
void afterPropertiesSet() throws Exception;
}
我们一般在XML中都会有这么一段配置,如下:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入连接池 -->
<property name="dataSource" ref="dataSource"/>
<!--主配置 -->
<property name="configuration">
<bean class="org.apache.ibatis.session.Configuration">
<property name="mapUnderscoreToCamelCase" value="true"/>
</bean>
</property>
<!-- 加载mybatis映射文件 -->
<property name="mapperLocations" value="classpath:mappers/*.xml"/>
</bean>
上述配置的作用就是让容器创建一个ID为sqlSessionFactory
的SqlSessionFactoryBean
实例,并且为实例指定了datasource
属性,手动指定了主配置对象,开启MyBatis
下划线转驼峰的属性配置,并且指定映射文件所在的位置。
注:
虽然指定的是SqlSessionFactoryBean
实例,但是因为继承了FactoryBean
接口,因此我们从容器拿到的对象实际上是getObject
方法返回的对象,即SqlSessionFactory
实例。
创建流程
首先自不用说,Spring会创建SqlSessionFactoryBean
实例,设置配置的所有属性,这是第一步,接下来便会走afterPropertiesSet()
方法。
@Override
public void afterPropertiesSet() throws Exception {
// 检查数据源
notNull(dataSource, "Property 'dataSource' is required");
// 检查SqlSessionFactoryBuilder, 已经在构造方法里初始化
notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
// configuration实例与configLocation只能有一个
state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
"Property 'configuration' and 'configLocation' can not specified with together");
// 解析配置文件,创建SqlSessionFactory。这属于MyBatis本身的内容,不再展开说明。
this.sqlSessionFactory = buildSqlSessionFactory();
}
创建SqlSessionFactory
的过程与MyBatis
不同的点主要在与transactionFactory
,在创建事务工厂时不再使用MyBatis
自带的JdbcTransaction
类,而是使用SpringManagedTransactionFactory
这个新的事务工厂类,这个事务获取到的连接全部来自于Spring管理,这样把事务全权交给Spring管理,而MyBatis
本身不再涉及事务管理。如果在使用Spring时没有配置(使用)事务,那么获取到的连接取决于DataSource
,无论拿到的连接是自动提交还是手动提交,MyBatis每一次方法调用都会视情况提交或回滚。当然对于自动提交而言,MyBatis的commit
或者rollbakc
是不会调用conn.commit()
或conn.rollback
。
在经过afterPropertiesSet
方法后,SqlSessionFactory
实例便创建完毕。需要使用SqlSessionFactory
实例便会调用getObject
方法。
@Override
public SqlSessionFactory getObject() throws Exception {
if (this.sqlSessionFactory == null) {
afterPropertiesSet();
}
return this.sqlSessionFactory;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构