前言
最近朋友和我提了一個挺有趣的問題:他們有個專案用了他們框架部提供的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