springboot 拦截器的坑 WebMvcConfigurationSupport 失效
大家好,我是烤鴨:
今天遇到一個(gè)攔截器失效的問題,具體看源碼分析下。
環(huán)境:
? ? springboot 2.x
? ? spring 5.x
1.? 先說下業(yè)務(wù)場(chǎng)景
需求是對(duì)請(qǐng)求進(jìn)入時(shí)和離開時(shí)對(duì)和線程id綁定,用的Threadlocal,現(xiàn)在有一個(gè)問題,利用攔截器的方式不生效。
2.? ?攔截器創(chuàng)建的幾種方式
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{}先說下結(jié)論,如果項(xiàng)目中出現(xiàn)了一次 extends WebMvcConfigurationSupport ,其他的 extends WebMvcConfigurationSupport 和 implements WebMvcConfigurer 會(huì)失效 。
3.?? 看下源碼為啥呢
先看下 WebMvcConfigurationSupport 這個(gè)類, addInterceptors 這個(gè)方法,默認(rèn)繼承的是 DelegatingWebMvcConfiguration,這個(gè)類就是獲取 `所有 ` 實(shí)現(xiàn) WebMvcConfigurer 的子類,調(diào)用他們的方法,如果有多個(gè) 通過實(shí)現(xiàn) WebMvcConfigurer 創(chuàng)建的攔截器,是都可以生效的。
那多個(gè) 繼承 WebMvcConfigurationSupport ?為啥只有一個(gè)生效呢,答案在這個(gè)類WebMvcAutoConfiguration 的 ConditionalOnMissingBean 注解,只實(shí)例化一個(gè)Bean,多個(gè)繼承也只有一個(gè)生效。
再看下 addInterceptors 啥時(shí)候觸發(fā)的,獲取攔截器的時(shí)候,獲取過就不再獲取了,所以 addInterceptors 在項(xiàng)目啟動(dòng)觸發(fā)才有效。而 getInterceptors 這個(gè)方法是在 handerMapping映射的時(shí)候觸發(fā)的(比如 RequestMappingHandlerMapping、BeanNameUrlHandlerMapping)。
4.?? 解決方案
針對(duì)不同的場(chǎng)景解決方案也不一樣,我想到的有3個(gè)方案。
- 不繼承 WebMvcConfigurationSupport ,攔截器全部通過實(shí)現(xiàn) WebMvcConfigurer 接口(推薦)
- 只繼承一次 WebMvcConfigurationSupport ,在這個(gè)類管理所有的攔截器(不推薦,耦合性太高)
- 針對(duì)我的場(chǎng)景,我通過 過濾器實(shí)現(xiàn)的。注入的代碼就不貼了,before 和 fater 方法實(shí)現(xiàn)了類似攔截器的 preHandle 和 afterCompletion。有一點(diǎn)需要注意的是指定過濾器的排序(默認(rèn)已經(jīng)是最高了,可以忽略),由于過濾器是鏈?zhǔn)秸{(diào)用,如果想當(dāng)攔截器用,必須指定最先加載,還有就是過濾器會(huì)攔截靜態(tài)資源,做好對(duì)靜態(tài)資源的放行。
這兩篇文章也是類似的問題,大家也可以看下:
https://www.lyscms.info/blog/detail/33A55BEE2FD94E66B40990EA4967D3F7
https://blog.csdn.net/pengdandezhi/article/details/81182701
總結(jié)
以上是生活随笔為你收集整理的springboot 拦截器的坑 WebMvcConfigurationSupport 失效的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python处理nc气象数据_气象数据处
- 下一篇: s3c2440移植MQTT