springboot 拦截器的坑 WebMvcConfigurationSupport 失效
大家好,我是烤鴨:
今天遇到一個攔截器失效的問題,具體看源碼分析下。
環境:
? ? springboot 2.x
? ? spring 5.x
1.? 先說下業務場景
需求是對請求進入時和離開時對和線程id綁定,用的Threadlocal,現在有一個問題,利用攔截器的方式不生效。
2.? ?攔截器創建的幾種方式
2.1 extends WebMvcConfigurationSupport
@Configuration public class WebMvcAutoConfigurationAdapter extends WebMvcConfigurationSupport {@AutowiredMapiHttpRequestInterceptor mapiHttpRequestInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {InterceptorRegistration addInterceptor = registry.addInterceptor(mapiHttpRequestInterceptor);// 攔截配置addInterceptor.addPathPatterns("/**");} }@Component class MapiHttpRequestInterceptor implements HandlerInterceptor{ }2.2 implements WebMvcConfigurer
@Configuration public class WebMvcAutoConfiguration3Adapter implements WebMvcConfigurer {@AutowiredMapiHttpRequest3Interceptor mapiHttpRequestInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {InterceptorRegistration addInterceptor = registry.addInterceptor(mapiHttpRequestInterceptor);// 攔截配置addInterceptor.addPathPatterns("/**");} }@Component class MapiHttpRequest3Interceptor implements HandlerInterceptor{}先說下結論,如果項目中出現了一次 extends WebMvcConfigurationSupport ,其他的 extends WebMvcConfigurationSupport 和 implements WebMvcConfigurer 會失效 。
3.?? 看下源碼為啥呢
先看下 WebMvcConfigurationSupport 這個類, addInterceptors 這個方法,默認繼承的是 DelegatingWebMvcConfiguration,這個類就是獲取 `所有 ` 實現 WebMvcConfigurer 的子類,調用他們的方法,如果有多個 通過實現 WebMvcConfigurer 創建的攔截器,是都可以生效的。
那多個 繼承 WebMvcConfigurationSupport ?為啥只有一個生效呢,答案在這個類WebMvcAutoConfiguration 的 ConditionalOnMissingBean 注解,只實例化一個Bean,多個繼承也只有一個生效。
再看下 addInterceptors 啥時候觸發的,獲取攔截器的時候,獲取過就不再獲取了,所以 addInterceptors 在項目啟動觸發才有效。而 getInterceptors 這個方法是在 handerMapping映射的時候觸發的(比如 RequestMappingHandlerMapping、BeanNameUrlHandlerMapping)。
4.?? 解決方案
針對不同的場景解決方案也不一樣,我想到的有3個方案。
- 不繼承 WebMvcConfigurationSupport ,攔截器全部通過實現 WebMvcConfigurer 接口(推薦)
- 只繼承一次 WebMvcConfigurationSupport ,在這個類管理所有的攔截器(不推薦,耦合性太高)
- 針對我的場景,我通過 過濾器實現的。注入的代碼就不貼了,before 和 fater 方法實現了類似攔截器的 preHandle 和 afterCompletion。有一點需要注意的是指定過濾器的排序(默認已經是最高了,可以忽略),由于過濾器是鏈式調用,如果想當攔截器用,必須指定最先加載,還有就是過濾器會攔截靜態資源,做好對靜態資源的放行。
這兩篇文章也是類似的問題,大家也可以看下:
https://www.lyscms.info/blog/detail/33A55BEE2FD94E66B40990EA4967D3F7
https://blog.csdn.net/pengdandezhi/article/details/81182701
總結
以上是生活随笔為你收集整理的springboot 拦截器的坑 WebMvcConfigurationSupport 失效的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python处理nc气象数据_气象数据处
- 下一篇: video和dvd audio区别: