日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

springboot 拦截器的坑 WebMvcConfigurationSupport 失效

發(fā)布時(shí)間:2023/12/10 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 springboot 拦截器的坑 WebMvcConfigurationSupport 失效 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

大家好,我是烤鴨:

今天遇到一個(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)資源的放行。
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {if (servletRequest instanceof HttpServletRequest) {HttpServletRequest request = (HttpServletRequest)servletRequest;this.before(request);filterChain.doFilter(servletRequest, servletResponse);this.after();} } @Bean public FilterRegistrationBean mapiXxxFilterRegister() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();filterRegistrationBean.setOrder(2147483647);filterRegistrationBean.setFilter(this.mapiXxxFilter);filterRegistrationBean.setName("filter-xxx");filterRegistrationBean.addUrlPatterns(new String[]{"/*"});return filterRegistrationBean; }

這兩篇文章也是類似的問題,大家也可以看下:

https://www.lyscms.info/blog/detail/33A55BEE2FD94E66B40990EA4967D3F7

https://blog.csdn.net/pengdandezhi/article/details/81182701

總結(jié)

以上是生活随笔為你收集整理的springboot 拦截器的坑 WebMvcConfigurationSupport 失效的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。