一、概述
已知拦截器能够拦截四种类型:Executor、ParameterHandler、ResultSetHandler、StatementHandler。
1.1、不同类型拦截器的执行顺序
背景:不同类型
项目地址:https://github.com/bjlhx15/mybatis.git 中的mybatis-interceptor-001 基础项目
顺序【Executor→StatementHandler→ParameterHandler→ResultSetHandler】
1、编写拦截器代码
2、mybatis.xml配置
<plugins> <!-- 拦截器配置 --> <plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestTypeInterceptorParameterHandler"/> <plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestTypeInterceptorResultSetHandler"/> <plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestTypeInterceptorStatementHandler"/> <plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestTypeInterceptorExecutor"/> </plugins>
3、执行测试输出
TestTypeInterceptorExecutor
[2019-07-29 10:37:25:540-http-nio-8080-exec-1] [INFO] - com.alibaba.druid.pool.DruidDataSource.init(DruidDataSource.java:930) - {dataSource-1} inited
TestTypeInterceptorStatementHandler
[2019-07-29 10:37:29:827-http-nio-8080-exec-1] [DEBUG] - org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:145) - ==> Preparing: select 'true' as QUERYID, id, name, version, balance from accountbalance
TestTypeInterceptorParameterHandler
[2019-07-29 10:37:31:177-http-nio-8080-exec-1] [DEBUG] - org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:145) - ==> Parameters:
TestTypeInterceptorResultSetHandler
可以看到不论配置文件如何,执行顺序如下:【Executor→StatementHandler→ParameterHandler→ResultSetHandler】
1.2、同类型位置不同
背景:同类型位置不同
项目地址:https://github.com/bjlhx15/mybatis.git 中的mybatis-interceptor-002 基础项目
顺序:数组上下位置倒序【3拦截前处理 > 2拦截前处理 > 1拦截前处理 > executor.query() > 1拦截后处理 > 2拦截后处理 > 3拦截后处理】
1、编写拦截器
2、编写xml
<plugins> <!-- 拦截器配置 --> <plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.Test1Interceptor"/> <plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.Test2Interceptor"/> </plugins>
3、执行测试输出
Test2Interceptor
Test1Interceptor
4、why
查看mybatis配置org.apache.ibatis.session.Configuration。中创建
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? this.defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Object 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 (this.cacheEnabled) {
executor = new CachingExecutor((Executor)executor);
}
Executor executor = (Executor)this.interceptorChain.pluginAll(executor);
return executor;
}
interceptorChain是在Configuration类中new出来的。它等价于mybatis-config中的<plugins></plugins>
查看 pluginAll添加顺序
private final List<Interceptor> interceptors = new ArrayList(); public InterceptorChain() { } public Object pluginAll(Object target) { Interceptor interceptor; for(Iterator i$ = this.interceptors.iterator(); i$.hasNext(); target = interceptor.plugin(target)) { interceptor = (Interceptor)i$.next(); } return target; }
可以看到 interceptorChain 拦截器顺序就是 配置顺序
但是在经过代理后,
3拦截前处理 > 2拦截前处理 > 1拦截前处理 > executor.query() > 1拦截后处理 > 2拦截后处理 > 3拦截后处理
1.3、同类型不同配置位置
背景:有spring中配置,还有mybatis中配置
项目地址:https://github.com/bjlhx15/mybatis.git 中的mybatis-interceptor-002 基础项目
顺序:数组上下位置倒序【mybatis配置拦截器2 > mybatis配置拦截器1 > spring配置拦截器2 >spring配置拦截器1 > executor.query() > spring配置拦截器1 > spring配置拦截器2 > mybatis配置拦截器1 > mybatis配置拦截器2 】
1、编写拦截器
2、spring中xml配置
<bean id="wrSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 实例化sqlSessionFactory时需要使用上述配置好的数据源以及SQL映射文件 --> <property name="dataSource" ref="wrDataSource"/> <property name="mapperLocations" value="classpath:mapper/auto/**/*.xml"/> <!-- mybatis的全局配置文件 如没有特需 可以不配置 --> <property name="plugins"> <array> <bean class="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestnterceptorIString1"/> <bean class="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestnterceptorIString2"/> </array> </property> <property name="configLocation" value="classpath:mybatis.xml"/> </bean>
mybatis中配置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <plugins> <!-- 拦截器配置 --> <plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestInterceptorMybatis1"/> <plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestInterceptorMybatis2"/> </plugins> </configuration>
3、输出
TestInterceptorMybatis2
TestInterceptorMybatis1
TestnterceptorIString2
TestnterceptorIString1
可以调整 spring中configLocation和plugins上下位置,输出一致
但是