Spring Boot 2中配置WebMvcConfigurer添加拦截器失败求助
咱们先梳理下你遇到的问题:在Spring Boot里配置HandlerInterceptor但始终不生效,先后试过继承WebMvcConfigurerAdapter(这个类其实已经过时了,推荐用WebMvcConfigurer接口)和实现WebMvcConfigurer加注解的方式都没成功。结合你的代码,我发现几个关键问题,咱们一步步来修复:
1. 去掉多余的@EnableWebMvc和重复的组件扫描
在Spring Boot中,@EnableWebMvc会完全接管Spring MVC的配置,关闭默认的WebMvcAutoConfiguration,这往往会导致很多自动配置的功能失效,除非你有明确的需求要完全自定义MVC配置,否则绝对不要加这个注解。
另外,你的启动类上的@SpringBootApplication已经包含了@ComponentScan、@EnableAutoConfiguration和@Configuration三个注解的功能,所以:
- WebConfig上的
@ComponentScan("com.*")完全多余,而且和启动类的扫描配置重复,容易出问题 - WebConfig只需要保留
@Configuration即可,它本身就是@Component的派生注解,会被自动扫描到
2. 修正WebConfig的构造方法与注入方式
你写的public WebConfig() { super(); }是错误的,因为WebMvcConfigurer是接口,没有父类构造方法,这个代码不仅没用,还可能引发不必要的问题,直接删掉。
另外,推荐用构造注入代替@Autowired字段注入,这是Spring官方推荐的最佳实践,能避免空指针问题,也更利于单元测试。
3. 明确拦截器的拦截路径
在注册拦截器时,最好明确指定addPathPatterns,比如/**表示拦截所有请求,否则默认可能只拦截部分路径,导致你误以为拦截器没生效。
修正后的完整代码
WebConfig类
@Configuration // 移除@EnableWebMvc和多余的@ComponentScan public class WebConfig implements WebMvcConfigurer { private final HandlerInterceptor headerModifierInterceptor; // 构造注入,无需@Autowired(Spring 4.3+支持) public WebConfig(RestTemplateHeaderModifierInterceptor headerModifierInterceptor) { this.headerModifierInterceptor = headerModifierInterceptor; } @Override public void addInterceptors(InterceptorRegistry registry) { System.out.println("------------------hi"); // 明确指定拦截所有路径 registry.addInterceptor(headerModifierInterceptor).addPathPatterns("/**"); } }
启动类
@SpringBootApplication @EnableWebSecurity @EntityScan("com") public class CoreRestAPIApplication { public static void main(String[] args) { SpringApplication.run(CoreRestAPIApplication.class, args); } }
这里移除了重复的@ComponentScan,因为@SpringBootApplication会自动扫描启动类所在包及其子包下的所有组件。
拦截器类
@Component public class RestTemplateHeaderModifierInterceptor implements HandlerInterceptor { private final AuthUtil authUtil; private final JwtTokenProvider jwtTokenProvider; // 构造注入代替字段注入 public RestTemplateHeaderModifierInterceptor(AuthUtil authUtil, JwtTokenProvider jwtTokenProvider) { this.authUtil = authUtil; this.jwtTokenProvider = jwtTokenProvider; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { String resolvedToken = jwtTokenProvider.resolveToken(request); if (!StringUtils.isEmpty(resolvedToken)) { String updatedToken = jwtTokenProvider.createToken( jwtTokenProvider.getUsername(resolvedToken), jwtTokenProvider.getAuthentication(resolvedToken).getAuthorities() ); response.addHeader(authUtil.AUTH_HEADER_NAME, updatedToken); } } }
这里顺便把字段注入改成了构造注入,避免潜在的空指针问题。
额外排查点
如果按上面修改后还是不生效,你可以做这几个检查:
- 确认WebConfig和拦截器类都在启动类的扫描范围内:比如启动类在
com.example包下,那么这两个类要在com.example或其子包下 - 查看控制台是否输出了
------------------hi:如果没输出,说明WebConfig没被Spring加载,那就是组件扫描的问题;如果输出了,说明拦截器已经注册,可能是请求路径没匹配上,检查你的请求是否符合/**的范围 - 确保你的请求是经过Spring MVC的
DispatcherServlet处理的:比如访问的是Controller的接口,而不是静态资源或者直接绕过Dispatcher的路径
内容的提问来源于stack exchange,提问作者Tal Aloni

