resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
return resultSetHandler;
}
public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
return statementHandler;
}
public Executor newExecutor(Transaction transaction, ExecutorType executorType, boolean autoCommit) {
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, autoCommit);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
可以很清楚看到这几个方法里面都调用了pluginAll方法。看了这几个方法名不用我解释这些方法是做什么的了吧?这就是我为什么说:MyBatis允许开发者在StatementHandler、ResultSetHandler、ParameterHandler以及Executor插入自己想执行的代码。pluginAll都是将new出来的对象传递过去,这就是target。这里就对pluginAll方法进行了介绍。那么接下来就对插件的核心部分进行介绍。
Plugin.wrap(target,this)这段代码是做了什么事?在这里我将为大家解开这神秘的面纱。首先看看wrap方法是做了什么:
[java] public static Object wrap(Object target, Interceptor interceptor) {
Map
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;
}
public static Object wrap(Object target, Interceptor interceptor) {
Map
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;
}
这个方法有来两个参数,第一个是target,第二个是interceptor。target就是我们要拦截的对象,及就是我们插件要放入到那个对象的代码中去,而interceptor就是开发人员开发的插件对象,此处貌似叫插件不是很合里,叫做拦截器更为合理,因为他是拦截MyBatis的执行过程,从而插入开发人员自己想执行的代码。此处就不就此问题纠结太久。发现在wrap方法里面第一行就调用了getSignatureMap方法,看到Signature这个单词不知是否很熟悉,这个在我们定义自己插件的时候貌似用到了:
[java] @Intercepts( {@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})})
public class StatementHandlerInterceptor implements Interceptor {
private String DIALECT ;
public String getDIALECT() {
return DIALECT;
}
public void setDIALECT(String dIALECT) {
DIALECT = dIALECT;
}
@Override
public Object intercept(Invoca