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继承问题思考
首先我们要对下面的五个类有基本的了解:
- WebMvcConfigurer
- WebMvcConfigurerAdapter
- WebMvcConfigurationSupport
- DelegatingWebMvcConfiguration
- WebMvcConfigurerComposite
关系如下:
- 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<WebMvcConfigurer> 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)文章来源:https://www.toymoban.com/news/detail-790306.html
如果还是觉得有点迷糊,那么记住以下两点即可:文章来源地址https://www.toymoban.com/news/detail-790306.html
- 容器中只需要维护一个WebMvcConfigurationSupport即可,多了会失效(最容易出错的情况就是在使用@EnableWebMvc的情况下,又去继承WebMvcConfigurationSupport进行配置)。
- 在使用了@EnableWebMvc的情况下,对springmvc的自定义配置实现WebMvcConfigurer是最稳妥的,因为DelegatingWebMvcConfiguration会对所以实现了WebMvcConfigurer的配置类进行收集然后去重写WebMvcConfigurationSupport中的空方法。
到了这里,关于SpringMVC中的拦截器不生效的问题解决以及衍生出的WebMvcConfigurationSupport继承问题思考的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!