自定义Mybatis拦截器 与PageHelper插件执行顺序问题
自定义Mybatis拦截器 与PageHelper插件执行顺序问题
问题:
自定义mybatis拦截器myInterceptor 在 PageHelper分页插件拦截器pageInterceptor后面执行。。
这不是项目想要的结果
myInterceptor :
pageInterceptor:
排查
写个配置类在项目启动时,debug查看一下mybatis拦截器链的顺序
/**
* mybatis拦截器配置
*/
@Configuration
public class MybatisInterceptorAutoConfiguration {
@Autowired
private List<SqlSessionFactory> sqlSessionFactoryList;
@PostConstruct //只会执行一次:
// 顺序:Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
public void addMysqlInterceptor() {
System.out.println(111);
}
}
发现myInterceptor 在pageInterceptor前面,但是pageInterceptor却先执行,可以得出mybatis拦截器链的执行顺序是倒着执行的
解决
思路:想办法吧myInterceptor 弄到pageInterceptor的后面去。
1.让自定义的拦截器不交由spring管理,在项目启动的时候自己new一个,添加到拦截器链的最后面
2.添加自定义拦截器到chain最后面
/**
* mybatis拦截器配置
*/
@Configuration
public class MybatisInterceptorAutoConfiguration {
@Autowired
private List<SqlSessionFactory> sqlSessionFactoryList;
@Autowired
private RedisService redisService;
@PostConstruct //只会执行一次:
// 顺序:Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
public void addMysqlInterceptor() {
//创建自定义mybatis拦截器,添加到chain的最后面
MybatisInterceptor mybatisInterceptor = new MybatisInterceptor();
mybatisInterceptor.setRedisService(redisService);//设置参数(根据实际情况)
for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
org.apache.ibatis.session.Configuration configuration = sqlSessionFactory.getConfiguration();
//自己添加
configuration.addInterceptor(mybatisInterceptor);
}
System.out.println(111);
}
}
3.debug查看
调整完成
修改后myInterceptor 就会在 pageInterceptor前面执行了
注意
需要拦截器拦截的是同一个目标方法,chain中拦截器执行顺序才会生效
比如myInterceptor 和pageInterceptor 拦截的都是拦截Excutor的query方法,可以生效
对象执行顺序如下(先---》后) (不受拦截器在chain中顺序控制)
-
1.Executor
(update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) -
2.ParameterHandler
(getParameterObject, setParameters) -
3.StatementHandler
(prepare, parameterize, batch, update, query) -
4.ResultSetHandler
(handleResultSets, handleOutputParameters)
例:
比如自定义拦截器T1拦截的是StatementHandler的prepare方法,
修改拦截器顺序后,如下
依然还是pageInterceptor 先执行