mybatis中拦截器执行顺序
拦截器初始化
在org.apache.ibatis.builder.xml.XMLConfigBuilder
中:
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);
}
}
}
可以发现XMLConfigBuilder
从interceptor
结点下依次按顺序的添加到configuration
中
在org.apache.ibatis.session.Configuration
中:
public void addInterceptor(Interceptor interceptor) {
interceptorChain.addInterceptor(interceptor);
}
可以看到从xml解析出来的interceptor最终被加入到interceptorChain
中
再看看interceptorChain
是如何执行interceptor
的,在org.apache.ibatis.plugin.InterceptorChain
中:
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
按照加入的顺序依次执行interceptor
操作
都知道拦截器链原理是:
interceptor1-preprocess...
interceptor2-preprocess...
interceptor3-preprocess...
target invoked...
interceptor3-postprocess...
interceptor2-postprocess...
interceptor1-postprocess...
拦截顺序
拦截顺序分成两种:对于同一对象的拦截和不同对象的拦截
不同对象的拦截
不同对象的拦截的顺序:
- Executor
- ParameterHandler
- StatementHandler
- ResultHandler
同一对象的拦截
主要看在xml中的位置,如果拦截的都是Executor
:
<property name="plugins">
<array>
<bean "interceptor1"/>
<bean "interceptor2"/>
</array>
</property>
即,interceptor1
在interceptor2
之前,那么就会先执行interceptor1
,后执行interceptor2
,interceptor2
执行结果返回至interceptor1
后作后置处理