聊聊如何讓springboot攔截器的執行順序按我們想要的順序執行

linyb極客之路發表於2022-03-15

前言

最近朋友和我提了一個挺有趣的問題:他們有個專案用了他們框架部提供的jwt token校驗填充元件,實現原理大概是,通過springboot攔截器來校驗token,如果token合法,就解析token,將token攜帶的業務資訊map填充到threadlocal裡面,方便後續業務使用。

朋友的問題就是他想往這個threalocal裡面的業務map再擴充套件一些業務欄位,但因為這個元件不是朋友的部門開發的,他就不能改原始碼,只能通過擴充套件的方式。

他的思路就是他也寫一個攔截器,在這個攔截器裡面做業務填充。這邊有個前提就是框架部的執行時機得在朋友寫的攔截器之前,朋友的做法是在他寫的攔截器上面加@Order註解,不過發現不管用。於是就找我討論一下這個問題。

抽象出來的問題就是標題說的如何讓springboot攔截器的執行順序按我們想要的順序執行

思路

方法一:自己的業務專案寫一個和框架組一模一樣的類

即這個類和框架組提供的包名和類名一樣,然後改這個類,這個實現原理是利用了類的載入順序

方法二:利用org.springframework.web.servlet.config.annotation.InterceptorRegistration#order()

不過這個order方法是spring 4.3+版本後才提供。

具體使用形如下

 @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(helloHandlerInterceptor).addPathPatterns("/**").order(100);
        registry.addInterceptor(otherHelloHandlerInterceptor).addPathPatterns("/**").order(-1);

    }

通過配置order()的值,值越小,優先順序越高。不配預設是0

那為啥要配置這個呢,如果對springmvc有稍微深入一下的話,攔截器鏈最終是會用到

protected List<Object> getInterceptors() {
        return this.registrations.stream()
                .sorted(INTERCEPTOR_ORDER_COMPARATOR)
                .map(InterceptorRegistration::getInterceptor)
                .collect(Collectors.toList());
    }

排序就是根據這個order來的

總結

本文提供的方案二適用於spring 4.3+版本,低於該版本,請慎重。

demo連結

https://github.com/lyb-geek/springboot-learning/tree/master/springboot-interceptor-order

相關文章