1. Interceptor 初始化 创建 Configuration,解析配置的interceptor 添加到 interceptorChain
String resource = "com/sxteng/mybatis/XMLConfigBuilder/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 构建 SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
XMLConfigBuilder parse 生成 Configuration
解析配置信息
parseConfiguration(XNode root)
解析插件并添加到Configuration中
pluginElement(root.evalNode("plugins"));
// 解析插件并添加到环境当中
private void pluginElement(XNode parent) throws Exception {
if (parent != null) {
for (XNode child : parent.getChildren()) {
String interceptor = child.getStringAttribute("interceptor");
Properties properties = child.getChildrenAsProperties();
Interceptor interceptorInstance = (Interceptor)
resolveClass(interceptor).newInstance();
//设置配置属性
interceptorInstance.setProperties(properties);
//将插件添加的配置中
configuration.addInterceptor(interceptorInstance);
}
}
}
2. 为Executor 应用插件,生成代理对象
打开session
SqlSessionFactory .openSession()
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);
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();
}
}
创建Executor, 应用插件, 生成代理对象
Configuration..newExecutor(tx, execType);
/**
* 创建Executor
* @param transaction
* @param executorType
* @return
*/
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
// 事物
executor = new SimpleExecutor(this, transaction);
}
//启动缓存
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
//应用插件
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
遍历拦截器
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
3 Interceptor 的 plugin(Object target) 方法 以PageHelper 为例
public Object plugin(Object target) {
if (target instanceof Executor) {
return Plugin.wrap(target, this);
} else {
return target;
}
}
4 Plugin 的 wrap(Object target, Interceptor interceptor) 如何有接口则创建代理对象
private Object target; //目标对象
private Interceptor interceptor;//拦截器
private Map<Class<?>, Set<Method>> signatureMap;//方法签名
public static Object wrap(Object target, Interceptor interceptor) {
Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
Class<?> type = target.getClass();
Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
if (interfaces.length > 0) {
return Proxy.newProxyInstance(
type.getClassLoader(),
interfaces,
new Plugin(target, interceptor, signatureMap));
}
return target;
}
InterceptorChain
Configuration XMLConfigBuilder.parse()
2 Configuration 重要属性
- InterceptorChain 插件
- proxyFactory