文章目录

SpringMVC中的拦截器不生效的问题解决WebMvcConfigurationSupport继承问题思考

SpringMVC中的拦截器不生效的问题解决

过滤器代码(被Spring扫描并管理):

@Component

public class StuInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

System.out.println("前置过滤器");

return true;

}

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

System.out.println("后置过滤器");

}

}

过滤器配置代码:

@Configuration

public class MvcSupport implements WebMvcConfigurer {

@Resource

private StuInterceptor stuInterceptor;

@Override

public void addInterceptors(InterceptorRegistry registry) {

System.out.println(stuInterceptor);

registry.addInterceptor(stuInterceptor).addPathPatterns("/stu");

}

}

按理说我们发出请求localhost/stu之后,应该可以看到过滤器的效果,但是失效了。

网上的说法众说纷纭:

没加@Component或者@Configuration注解@ComponentScan没扫描到路径配置错了

以上三种说法一一排除之后,我发现一个博客提到了:

我想到在SpringMVC的配置类上使用了@EnableWebMvc注解,而这个注解相当于在容器中引入了DelegatingWebMvcConfiguration类,而这个DelegatingWebMvcConfiguration类是继承于WebMvcConfigurationSupport的: 于是我把@EnableWebMvc这个注解去掉之后再进行尝试,发现过滤器生效:

WebMvcConfigurationSupport继承问题思考

首先我们要对下面的五个类有基本的了解:

WebMvcConfigurerWebMvcConfigurerAdapterWebMvcConfigurationSupportDelegatingWebMvcConfigurationWebMvcConfigurerComposite

关系如下:

WebMvcConfigurer 接口提供了很多方法让我们来定制SpringMVC的配置WebMvcConfigurationSupport是一个具体类,其中有很多 @Bean 的方法,注入 SpringMVC 的一些关键组件,方法中会调用一些空方法,子类只需重写这些空方法就可以实现定制SpringMVC,而WebMvcConfigurationAdapter则是一个抽象类WebMvcConfigurationSupport、WebMvcConfigurationAdapter都可以实现配置SpringMVC,即都可以配置视图解析器、拦截器以及静态资源等WebMvcConfigurerAdapter 实现了WebMvcConfigurer ,所有方法实现都是空实现,且为抽象类,子类只需覆盖感兴趣的方法即可。在 Spring5.0 开始,WebMvcConfigurer 接口的所有方法都改为了默认方法(基于java8),所以就 不再需要WebMvcConfigurerAdapter类 了,也加上了@Deprecated,子类直接实现 WebMvcConfigurer 即可。WebMvcConfigurationSupport 支持的自定义的配置更多更全,WebMvcConfigurerAdapter有的方法,这个类也都有。该类是提供MVC Java config 背后配置的主要类。 通常是通过将@EnableWebMvc添加到应用程序的@Configuration类中来导入的。 另一个更高级的选择是直接从此类扩展并在需要时重写方法,记住子类要添加@Configuration,重写带有@Bean的方法也要加上@Bean。@EnableWebMvc=WebMvcConfigurationSupport,使用了@EnableWebMvc注解等于扩展了WebMvcConfigurationSupport但是没有重写任何方法DelegatingWebMvcConfiguration由@EnableWebMvc注解引入,它继承了WebMvcConfigurationSupport在DelegatingWebMvcConfiguration 类中,有个 @Autowired 的方法 setConfigurers(List configurers),获取Spring容器的所有 WebMvcConfigurer 类型的bean,存储到 WebMvcConfigurerComposite 类型的 configurers 属性中。然后利用上面的 configurers 属性重写 WebMvcConfigurationSupport 中所有的空方法

另外,WebMvcConfigurationSupport(@EnableWebMvc)和@EnableAutoConfiguration这两种方式都有一些默认的设定。所以有以下几种使用方式:

@Configuration + @EnableWebMvc + extends WebMvcConfigurer ,在扩展的类中重写父类的方法即可,但会使springboot的@EnableAutoConfiguration自动配置失效@Configuration + extends WebMvcConfigurationSupport,在扩展的类中重写父类的方法即可,但会使springboot的@EnableAutoConfiguration自动配置失效@Configuration + extends WebMvcConfigurer ,在扩展的类中重写父类的方法即可,这种方式依旧使用springboot的@EnableAutoConfiguration中的设置

WebMvcConfigurationSupport类是彻底自定义配置springmvc,若容器中有该类的子类bean,则springboot的自动配置都会失效,因为WebMvcAutoConfiguration类有 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

如果还是觉得有点迷糊,那么记住以下两点即可:

容器中只需要维护一个WebMvcConfigurationSupport即可,多了会失效(最容易出错的情况就是在使用@EnableWebMvc的情况下,又去继承WebMvcConfigurationSupport进行配置)。在使用了@EnableWebMvc的情况下,对springmvc的自定义配置实现WebMvcConfigurer是最稳妥的,因为DelegatingWebMvcConfiguration会对所以实现了WebMvcConfigurer的配置类进行收集然后去重写WebMvcConfigurationSupport中的空方法。

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: