找到一篇好文章,主要在这篇文章的下面五. Mybatis源码分析:https://www.codercto.com/a/35503.html
MybatisAutoConfiguration中的sqlSessionFactory(DataSource dataSource)中设置参数=======>SqlSessionFactoryBean(先设置参数,在用getObject()方法取出SqlSessionFactory对象)=========>getObject()方法调用 afterPropertiesSet()方法==========>afterPropertiesSet()方法中调用buildSqlSessionFactory()方法===========>buildSqlSessionFactory()中根据参数设置configuration==============>sqlSessionFactoryBuilder.build(configuration)方法 返回一个DefaultSqlSessionFactory
1. org.mybatis.spring.boot.autoconfigure下的MybatisAutoConfiguration类
声明 SqlSessionFactory,SqlSessionTemplate等等,
创建SqlSessionFactory的bean
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnBean({DataSource.class})
@EnableConfigurationProperties({MybatisProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class})
public class MybatisAutoConfiguration {
private static final Logger logger = LoggerFactory.getLogger(MybatisAutoConfiguration.class);
private final MybatisProperties properties;
private final Interceptor[] interceptors;
private final ResourceLoader resourceLoader;
private final DatabaseIdProvider databaseIdProvider;
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
//设置dataSource
factory.setDataSource(dataSource);
//VFS是用于访问服务器资源的接口,SpringBootVFS是VFS的子类,用于在springboot环境下访问服务器资源
factory.setVfs(SpringBootVFS.class);
if (StringUtils.hasText(this.properties.getConfigLocation())) {
/**mybatis xml配置文件的位置(非application.propertity配置采用xml配置mybatis属性时才为非空)。
*非null时,会加载该位置的文件成为 stream(流)设置到factory中
*/
factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
}
factory.setConfiguration(this.properties.getConfiguration());
if (this.properties.getConfigurationProperties() != null) {
//mybatis配置的外部属性。指定的属性可以用作mybatis配置文件和映射器文件的占位符 factory.setConfigurationProperties(this.properties.getConfigurationProperties());
}
if (!ObjectUtils.isEmpty(this.interceptors)) {
//拦截器,org.apache.ibatis.plugin.Interceptor接口,plugin插件包中,用于给mybatis相关插件使用的接口,如PageHelper分页插件等
factory.setPlugins(this.interceptors);
}
if (this.databaseIdProvider != null) {
//databaseIdProvider元素主要是为了支持不同厂商的数据库
factory.setDatabaseIdProvider(this.databaseIdProvider);
}
if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
//数据库映射实体所在的包
factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
}
if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
//实体属性类型 如:String <====> varcher这样的对应关系
factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
}
if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
//mapper映射文件位置,有就形成流的形式放入factory中
factory.setMapperLocations(this.properties.resolveMapperLocations());
}
return factory.getObject();
}
//等等其他方法
}
2. 进入 org.mybatis.spring 中的 SqlSessionFactoryBean
public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {
//FactoryBean接口有一个getObject()方法,返回的是<T>中的T的对象
@Override
public SqlSessionFactory getObject() throws Exception {
if (this.sqlSessionFactory == null) {
afterPropertiesSet();
}
return this.sqlSessionFactory;
}
/**InitializingBean接口中只有一个afterPropertiesSet()方法,
* 这个方法将在所有的属性被初始化后调用。
*/
@Override
public void afterPropertiesSet() throws Exception {
//notNull非空判断
notNull(dataSource, "Property 'dataSource' is required");
notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
"Property 'configuration' and 'configLocation' can not specified with together");
this.sqlSessionFactory = buildSqlSessionFactory();
}
//创建SqlSessionFactory对象
protected SqlSessionFactory buildSqlSessionFactory() throws IOException {
Configuration configuration;
//一系列配置configuration的属性值(包括sql语句执行中所涉及的 实体,mapper文件,插件,resultMap,属性类型等等一系列相关值)
//最后返回sqlSessionFactoryBuilder中的build(Configuration configuration)方法
return this.sqlSessionFactoryBuilder.build(configuration);
}
}