微信优化

weixinyouhua

Spring配置拦截器怎么做?Spring MVC拦截器配置方法

2026-10-15 12:04:22

Spring配置拦截器的核心答案是:通过实现HandlerInterceptor接口并注册到Spring MVC的拦截器注册表中,登录鉴权、日志记录、接口防重等横切逻辑就能在Controller方法执行前后自动运行。这套机制在Spring Boot项目中通常只需要一个@Configuration类加上几行addInterceptors代码,但在Spring传统XML项目中则是另一套配置路径,下面把三种主流配置方式、常见坑位以及和过滤器(Filter)的本质区别一次讲透。

用代码配置拦截器:从Spring Boot到传统项目的完整姿势

Spring Boot下的Java Config配置(最常用)

在Spring Boot 2.x和3.x环境下,配置拦截器的标准姿势是写一个配置类,实现WebMvcConfigurer接口,重写addInterceptors方法,这是目前绝大多数项目的选项路径。

  • 第一步:自定义拦截器类,实现HandlerInterceptor接口,在preHandle、postHandle、afterCompletion三个方法中写业务逻辑。
  • 第二步:注册拦截器,使用@Configuration注解的类继承WebMvcConfigurer,调用registry.addInterceptor()方法添加。
  • 第三步:通过addPathPatterns指定拦截路径,用excludePathPatterns放行登录、注册、静态资源等路径。

以一个登录校验拦截器为例,preHandle中从request的Header或Session中取出Token,若为空则直接返回false并写入“未授权”JSON响应,这种写法相比在每个Controller里重复判断代码,维护成本低一个量级。

传统Spring XML项目的配置方法

不少遗留系统依然使用Spring MVC的XML配置方式,在spring-mvc.xml中,通过标签声明拦截器,子标签包裹bean定义和mvc:mapping路径,行业共识认为,这种方式虽然配置冗长,但对老项目的改造风险最小,不需要动业务代码。

一个容易踩坑的注册细节

如果项目中使用Spring Security,注册拦截器的配置类上需要加@EnableWebMvc注解吗?一般不推荐加,加了@EnableWebMvc会全面接管WebMvc配置,导致静态资源映射、消息转换器等默认配置失效,多数情况下会出现“配置了拦截器但CSS、JS全部404”的现象,处理费时费力。

Spring配置拦截器怎么做?Spring MVC拦截器配置方法

spring拦截器不生效的5大排查路径

按拦截器配置失败的常见原因,按下述顺序检查可较快定位问题:

  • 项目是否引入了spring-webmvc依赖,仅依赖spring-context时不会触发WebMvcConfigurer机制。
  • 自定义拦截器类上是否标注@Component或交由Spring容器管理,注册时若直接new一个拦截器实例,其中的依赖注入全部为null,preHandle里调用Service必然抛空指针。
  • 路径匹配规则是否写对,/匹配所有路径,/只匹配一层路径,/api/不匹配/api/user/detail这种多级路径。
  • Spring Boot版本差异:Spring Boot 2.x用WebMvcConfigurer没问题,Spring Boot 3.x基于Jakarta Servlet的API,拦截器方法签名没有变化,但依赖包名变化会编不过。
  • 多拦截器顺序问题:后注册的拦截器preHandle先执行,postHandle和afterCompletion逆序执行,若A拦截器放行了请求但B拦截器阻止,A的afterCompletion依然会执行,这在业务上容易造成“日志记录了但接口其实没成功”的误会。

spring拦截器和过滤器区别的对比梳理

很多初级开发者分不清Filter和Interceptor的边界,从执行时机来看:Filter由Servlet容器管理,在请求进入DispatcherServlet之前执行;Interceptor在DispatcherServlet匹配到具体Handler之后执行,从使用场景看,Filter更适合处理编码设置、跨域CORS、请求体流读取这类Web层通用逻辑,而Interceptor更贴合Spring MVC的Handler执行链路,可以直接拿到HandlerMethod、ModelAndView等MVC相关对象。

Spring配置拦截器怎么做?Spring MVC拦截器配置方法

对比维度 Filter(过滤器) Interceptor(拦截器)
规范归属 Servlet规范 Spring MVC规范
执行时机 进入DispatcherServlet之前 Handler执行之前/之后
能否获取Spring Bean 可以注入但需容器管理 天然支持,可直接注入
典型场景 字符编码、跨域、请求日志 登录校验、权限控制、接口幂等
终止方式 直接返回响应 返回false并写入响应

从配置到实战:一个完整的登录拦截器实例与性能考量

写一个可运行的登录校验拦截器,多数实际项目还会搭配用户权限标识动态下发,业界通常的做法是:preHandle中从请求头读取token,调用自定义的TokenService验证有效期,若token剩余有效时间低于阈值则刷新并写入响应头,这个逻辑放在拦截器里比放在Controller里更加优雅。

拦截器中的异步请求与性能监控

当接口中使用Callable或DeferredResult处理异步逻辑时,postHandle不会在业务线程执行后继续触发,需要在异步请求完成时通过WebAsyncManager注册拦截器,若没有注册,性能监控类拦截器在异步接口下会漏记日志。

登录拦截器里放行路径顺序有讲究

分两批放行效果更清晰:

  • 第一批:静态资源,/static/、/favicon.ico、/error。
  • 第二批:白名单接口:/login、/captcha、/api/register,优先使用精确路径匹配而不是/通配符兜底。

这样配置后,后续只要在Controller路径上做权限注解标注,就行之有效,而不必频繁改动拦截器。

实战中的多拦截器链与顺序控制

业务复杂时,通常会配置多个拦截器分别处理日志、登录校验、权限校验、接口幂等,注册顺序就是执行顺序,先注册的外层先执行preHandle,具体配置时的操作经验是:把通用性强的放前面,业务性强的放后面。

三个拦截器配置示例路径:

  • 第一个:AccessLogInterceptor,打印请求方法、URI、耗时,使用/路径。
  • 第二个:AuthInterceptor,校验用户身份,使用/api/路径,排除/login。
  • Spring配置拦截器怎么做?Spring MVC拦截器配置方法

  • 第三个:RateLimitInterceptor,基于Redis限流,使用//write等写接口路径。

在排除路径列表中,需要把文档接口(如swagger-ui、/v3/api-docs)排除掉,否则在开发环境调试接口时突遇登录跳转会降低联调效率。

Spring配置拦截器后的性能收益与常见误区

配置拦截器维护横切逻辑,相比在Controller中复制粘贴代码,性能上只是多了一次方法调用和一次布尔判断,开销很小,真正的性能瓶颈常出现在拦截器中执行了数据库查询、远程RPC调用这类重量级操作,尤其在高并发下接口访问量较大时,容易拖慢请求链路,建议把拦截器内的逻辑保持轻量,避免在这个位置访问第三方接口或执行耗时聚合操作,多数情况下,将用户信息查询从拦截器挪到Controller内按需加载,能有效降低无权限请求的资源消耗。

关于Spring拦截器配置有哪些常见疑问

spring拦截器配置方法有哪些?

配置拦截器有Java Config和XML两种主流方式,Java Config使用WebMvcConfigurer接口配合addInterceptors方法注册,XML使用mvc:interceptors标签声明,Spring Boot项目采用Java Config的方式更加简洁,同时支持路径匹配和排除规则的高度定制。

登录拦截器里校验不通过时如何返回JSON?

在preHandle中使用response.setContentType(“application/json;charset=UTF-8”),然后通过response.getWriter().write(JSON字符串)直接输出统一响应体,最后return false终止请求,注意此时不要直接使用HttpServletResponse.sendRedirect,那样会导致前后端分离模式下前端拿不到结构化错误信息。

拦截器和AOP的关系是什么?

拦截器基于Servlet容器的调用链机制,在Handler执行前后回调,天然适配MVC层,而AOP基于Spring容器管理的Bean代理,可以切到Service层的任意方法,实现更细粒度的日志、事务、权限逻辑,两者并不冲突,执行层级和执行目标不同,在实际工程中常常搭配使用。

相关文章

2024年,SaaS软件行业碰到获客难、增长慢等问题吗?

我们努力让每一次邂逅总能超越期待