接着上面博客内容Myabtis源码分析-SqlSessionFactory,这里讲解sqlSession相关源码内容。
直接进入源码 openSession方法,默认接口实现类 DefaultSqlSessionFactory#openSessionFromDataSource: 这个函数核心目的就是创建一个Excutor
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
// 创建事务
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
// 创建Executor执行器参数:事务tx,执行器类型
final Executor executor = configuration.newExecutor(tx, execType);
// 返回DefaultSqlSession,其封装了configuration、executor等属性
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
进入newExecutor方法查看:这里主要就是选出用户设置或者默认的类型的执行器:
SIMPLE 就是普通的执行器;
REUSE 执行器会重用预处理语句(PreparedStatement);
BATCH 执行器不仅重用语句还会执行批量更新。
如果设置了二级缓存,这里会对Excutor进行一次包装,最后执行插件
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
// BATCH 执行器不仅重用语句还会执行批量更新。
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
// REUSE 执行器会重用预处理语句(PreparedStatement) 默认
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
//SIMPLE 就是普通的执行器
executor = new SimpleExecutor(this, transaction);
}
// 如果开启了二级缓存,这里会对执行器进行一次包装,但是底层还是一样的执行器
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
// 注意:这里通过 拦截链 执行了插件,就以为着我们自定义插件时,这里会被执行,如果需要
// 自定义对执行器修改的插件,这里就是其执行作用的原理。
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
pluginAll方法,主要遍历所有插件,执行其plugin方法。
总结: SqlSession默认实现类是DefaultSqlSession,底层通过其openSessionFromDataSource方法,实现了创建事务和默认执行器,如果设置了二级缓存会使用CachingExecutor对其包装,然后通过拦截链执行插件plugin方法,最后返回DefaultSqlSession实例,封住configuration和executor等属性。
注意:SqlSession = DefaultSqlSession:内存含有Configuration(配置信息)和Executor信息,并在创建Excutor时执行了一次拦截链插件方法。