1、进入到openSession()方法, 因为sqlSessionFactory在运行时的对象为DefaultSqlSessionFactory, 所以通过动态绑定机制调用的openSession为DefaultSqlSessionFactory的
@Override
public SqlSession openSession(boolean autoCommit) {
// configuration.getDefaultExecutorType() 为默认的SIMPLE类型的执行器
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
}
2、进入到DefaultSqlSessionFactory类的openSessionFromDataSource方法中
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执行器对象
final Executor executor = configuration.newExecutor(tx, execType);
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();
}
}
3、进入Configuration类的newExecutor(tx, execType)方法
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
// 此处根据全局配置文件中配置的ExecutorType的类型, 来创建不同的XxxExecutor
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
// 默认是SIMPLE类型, 所以创建SimpleExecutor对象
executor = new SimpleExecutor(this, transaction);
}
// 如果有二级缓存, 就会创建CachingExecutor对象
/*
该对象内部调用的查询方法对象, 实际还是传进去的executor
*/
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
public enum ExecutorType {
// BATCH为批量执行器
SIMPLE, REUSE, BATCH
}
Executor : 每一个SqlSession都会拥有一个Executor对象,这个对象负责增删改查的具体操作,我们可以简单的将它理解为JDBC中Statement的封装版。
4、进入CachingExecutor看一下
public class CachingExecutor implements Executor {
private final Executor delegate;
private final TransactionalCacheManager tcm = new TransactionalCacheManager();
public CachingExecutor(Executor delegate) {
this.delegate = delegate;
delegate.setExecutorWrapper(this);
}
// 省略...
@Override
public List query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
throws SQLException {
Cache cache = ms.getCache();
if (cache != null) {
flushCacheIfRequired(ms);
if (ms.isUseCache() && resultHandler == null) {
ensureNoOutParams(ms, boundSql);
@SuppressWarnings("unchecked")
List list = (List) tcm.getObject(cache, key);
if (list == null) {
// 使用的仍然是传进来的executor
list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
tcm.putObject(cache, key, list); // issue #578 and #116
}
return list;
}
}
// 使用的仍然是通过构造器传进来的executor
return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
5、newExecutor方法最终返回的executor对象都要走InterceptorChain类的pluginAll方法, 来将executor对象通过每个拦截器包装一下, 并返回最终的executor
executor = (Executor) interceptorChain.pluginAll(executor);
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
6、最终将这个包装好的executor对象, 传入到DefaultSqlSession中 7、最终调用的openSession()方法, 会返回一个DefaultSqlSession对象
1-7时序图如下:
总结: 返回的SqlSession的实现类DefaultSqlSession对象, 它包含了Executor和Configuration。Executor
会在这一步被创建
1、进入DefaultSqlSession类的getMapper(Class class)方法
// 进入到DefaultSqlSession的getMapper方法
@Override
public T getMapper(Class type) {
// 调用configuration的getMapper
return configuration.getMapper(type, this);
}
// 进入到Configuration的getMapper方法
public T getMapper(Class type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}
2、进入到MapperRegistry类的getMapper方法
public T getMapper(Class type, SqlSession sqlSession) {
// 直接从knownMappers拿到type的MapperProxy对象
final MapperProxyFactory mapperProxyFactory = (MapperProxyFactory) knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
try {
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
3、进入mapperProxyFactory.newInstance(sqlSession)方法
// MapperProxyFactory类的方法
public T newInstance(SqlSession sqlSession) {
// 创建了MapperProxy对象
// public class MapperProxy implements InvocationHandler, Serializable {}
// 所以MapperProxy
final MapperProxy mapperProxy = new MapperProxy(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
// 进入newInstance(MapperProxy proxy)方法
// 创建MapperProxy代理对象
protected T newInstance(MapperProxy mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
4、最终就创建了UserMapper接口的代理对象
时序图如下: