本文基于mybatis-spring 1.3.1和mybatis 3.4.4版本
mybatis提供了mybatis-spring-boot-autoconfigure工程用作spring boot环境下自动配置mybatis。
首先看一下该工程下的spring.factories文件:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
该文件配置了MybatisAutoConfiguration作为mybatis的自动配置类。本文下面将详细分析该类。
MybatisAutoConfiguration类有如下注解:
@org.springframework.context.annotation.Configuration
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@ConditionalOnBean(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
从注解上可以看出该类依赖于DataSource实例,mybatis使用的配置类是MybatisProperties,使用XML文件配置的大部分属性都可以通过MybatisProperties配置。
下面是构造方法:
public MybatisAutoConfiguration(MybatisProperties properties,
ObjectProvider<Interceptor[]> interceptorsProvider,
ResourceLoader resourceLoader,
ObjectProvider<DatabaseIdProvider> databaseIdProvider,
ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider) {
this.properties = properties;//MybatisProperties实例
//引入插件,mybatis自动加载实现Interceptor接口的实例
this.interceptors = interceptorsProvider.getIfAvailable();
this.resourceLoader = resourceLoader;
//自动加载DatabaseIdProvider实例,DatabaseIdProvider用于设置使用的数据库产品,比如mysql、oracle等
this.databaseIdProvider = databaseIdProvider.getIfAvailable();
//自动加载ConfigurationCustomizer实例
//ConfigurationCustomizer用于对Configuration实例做出自定义处理
this.configurationCustomizers = configurationCustomizersProvider.getIfAvailable();
}
插件是这里面比较重要的东西,以前使用XML文件配置,必须在XML文件指定插件,现在只需实现Interceptor接口即可,mybatis会自动加载插件。
MybatisAutoConfiguration提供了两个非常重要的方法:
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception{}
@Bean
@ConditionalOnMissingBean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {}
sqlSessionFactory()用于创建SqlSessionFactory对象,SqlSessionFactory是SqlSession工厂。默认是DefaultSqlSessionFactory,DefaultSqlSessionFactory的构造方法非常简单:
public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}
DefaultSqlSessionFactory的入参只有Configuration对象,所以MybatisAutoConfiguration.sqlSessionFactory()主要是收集各种配置,将这些配置信息存入Configuration对象,最后使用Configuration对象创建DefaultSqlSessionFactory。这些配置信息的来源可以有:
- MybatisProperties实例,也就是spring boot配置文件;
- mybatis XML配置文件(当使用MybatisAutoConfiguration自动配置mybatis时,不会读取mybatis的XML配置文件。);
- Configuration对象的默认设置。
再来看一下MybatisAutoConfiguration.sqlSessionTemplate方法,该方法非常简单:
@Bean
@ConditionalOnMissingBean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
ExecutorType executorType = this.properties.getExecutorType();
if (executorType != null) {
return new SqlSessionTemplate(sqlSessionFactory, executorType);
} else {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
sqlSessionTemplate()直接创建了SqlSessionTemplate实例。那么SqlSessionTemplate的作用是什么?
mybatis对每个Mapper接口创建一个代理对象,我们在程序中便是使用该代理对象访问数据库。当程序调用代理对象的方法时,代理对象内部会将请求委托给SqlSessionTemplate,SqlSessionTemplate首先检查当前事务是否有SqlSession对象,如果没有则创建SqlSession对象,然后将请求委托为SqlSession对象,SqlSession再去访问数据库获得结果。
MybatisAutoConfiguration还有一个内部类MapperScannerRegistrarNotFoundConfiguration,但是一般我们会在应用程序中使用注解@MapperScan,当有了@MapperScan,MapperScannerRegistrarNotFoundConfiguration便不会被加载使用。