自定義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 先執行


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM