Mybatis源码解析之核心类分析
Mybatis源码解析之初始化分析
Mybatis源码解析之执行流程解析
Mybatis源码解析之数据库连接和连接池
Mybatis源码解析之事务管理
Mybatis源码解析之缓存机制(一):一级缓存
Mybatis源码解析之缓存机制(二):二级缓存
Mybatis源码解析之插件机制
Mybatis源码解析之mapper接口的代理模式
Mybatis源码解析之DefaultResultSetHandler的handleResultSets方法解析
前面的几篇相关博客都针对原生的mybatis进行解析,从本文开始将针对mybatis和spring的集成进行解析。若无特殊说明,所有的源码都基于org.mybatis:mybatis-spring:1.3.1的jar包
一、jar包介绍
mybatis-spring是spring与mybatis的集成jar包,因此对spring和mybatis的相关jar包都存在依赖。
二、配置文件
在spring中集成mybatis框架,主要需要对以下两者进行bean注入。
1. SqlSessionFactory
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>
SqlSessionFactory通过SqlSessionFactoryBeanFactory注入,其中的configLocation指定mybatis的配置文件,datasource指定数据源,我们还可以通过property注入其他的一些属性,不在意义列举,通过后续的源码解析会有一定了解。
2. mapper
除了SqlSessionFactory外,我们还有必要将mapper接口进行注入,可以通过注解、配置文件等多种方式注入,此处分别以MapperFactoryBean和MapperScannerConfigurer两种方式为例。
//MapperFactoryBean单个注入
<bean id="xxxMappper" class="org.mybatis.Spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.xxx.mapper.xxxMapper">
<peroperty name="sqlSessionFactory" value="sqlSessionFactory">
</bean>
//MapperScannerConfigurer路径扫描批量注入
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xxx.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
三、SqlSessionFactoryBean
SqlSessionFactoryBean实现类FactoryBean和InitializingBean接口,基于spring的了解我们明白其注入的是getObject()方法的返回值,跟踪方法的调用,我们可以发现核心逻辑在SqlSessionFactoryBean#buildSqlSessionFactory()方法中。
1. SqlSessionFactoryBean#buildSqlSessionFactory()
protected SqlSessionFactory buildSqlSessionFactory() throws IOException {
Configuration configuration;
//configuration的几种配置方式
XMLConfigBuilder xmlConfigBuilder = null;
if (this.configuration != null) {
configuration = this.configuration;
if (configuration.getVariables() == null) {
configuration.setVariables(this.configurationProperties);
} else if (this.configurationProperties != null) {
configuration.getVariables().putAll(this.configurationProperties);
}
} else if (this.configLocation != null) {
xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
configuration = xmlConfigBuilder.getConfiguration();
} else {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Property 'configuration' or 'configLocation' not specified, using default MyBatis Configuration");
}
configuration = new Configuration();
if (this.configurationProperties != null) {
configuration.setVariables(this.configurationProperties);
}
}
//objectFactory配置
if (this.objectFactory != null) {
configuration.setObjectFactory(this.objectFactory);
}
//objectWrapperFactory 配置
if (this.objectWrapperFactory != null) {
configuration.setObjectWrapperFactory(this.objectWrapperFactory);
}
//v