珍惜当下 展望未来!

自定义Mybatis拦截器 与PageHelper插件执行顺序问题

自定义Mybatis拦截器 与PageHelper插件执行顺序问题

问题:

自定义mybatis拦截器myInterceptor 在 PageHelper分页插件拦截器pageInterceptor后面执行。。

这不是项目想要的结果

myInterceptor :

image-20211221112834373

pageInterceptor:

image-20211221115403341

排查

写个配置类在项目启动时,debug查看一下mybatis拦截器链的顺序


/**
 * mybatis拦截器配置
 */
@Configuration
public class MybatisInterceptorAutoConfiguration {
    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;
    
      @PostConstruct //只会执行一次:
    // 顺序:Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
    public void addMysqlInterceptor() {
        System.out.println(111);

    }

}

image-20211221113156110

发现myInterceptor 在pageInterceptor前面,但是pageInterceptor却先执行,可以得出mybatis拦截器链的执行顺序是倒着执行的

解决

思路:想办法吧myInterceptor 弄到pageInterceptor的后面去。

1.让自定义的拦截器不交由spring管理,在项目启动的时候自己new一个,添加到拦截器链的最后面

image-20211221113801116

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查看

image-20211221114450836

调整完成

修改后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方法,

image-20211221121159004

修改拦截器顺序后,如下

image-20211221121126996

依然还是pageInterceptor 先执行

posted @ 2021-12-20 17:53  嘿嘿-  阅读(6124)  评论(1编辑  收藏  举报