当前位置:首页 > 虚拟主机 > 正文

Spring配置拦截器怎么做,Spring拦截器如何配置

Spring拦截器配置的核心结论:拦截器是Spring MVC中实现请求预处理与后处理的轻量级组件,正确配置的关键在于明确拦截范围、执行顺序与静态资源放行策略,推荐基于Java Config的方式替代XML配置,以提升可维护性与类型安全。

拦截器在Spring架构中的定位与价值

Spring拦截器(HandlerInterceptor)并不等同于Servlet规范中的Filter,它作用于DispatcherServlet分发Handler(Controller方法)的前后,能够对请求进行精细化控制,适用场景包括登录鉴权、权限校验、接口幂等性处理、请求日志记录、敏感操作审计等,相比Filter,拦截器可以访问Spring容器中的Bean,并能通过HandlerMethod获取目标方法元数据,实现更细粒度的控制。

在分层架构中,拦截器位于Controller入口之前,能有效减少业务代码中的重复横切逻辑,避免在多个Controller方法中编写相同的校验代码,合理使用拦截器,还可显著提升系统的安全性、可观测性与响应效率。

拦截器配置的三种核心方式与选型建议

基于Java Config(推荐,最常用)

Spring Boot或Spring 5+项目中,推荐实现WebMvcConfigurer接口并重写addInterceptors方法:

@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()) .addPathPatterns("/api/") .excludePathPatterns("/api/login", "/api/register", "/error"); } }

关键点:addPathPatterns定义拦截范围,支持Ant通配符(如、/admin/);excludePathPatterns必须显式放行静态资源与无需鉴权的接口,否则会导致资源加载失败或登录接口被无谓拦截。

基于XML配置(传统方式)

适用于旧版Spring MVC项目,在spring-mvc.xml中配置:

Spring配置拦截器怎么做,Spring拦截器如何配置 第1张

此方式配置冗长且无法在编译期发现类型错误,仅建议在遗留系统维护时使用

使用第三方拦截器组件

如Shiro、Spring Security内置的拦截器,或自定义注解配合拦截器实现权限控制,此方式适合有复杂安全需求的场景,但会增加框架耦合度,需根据项目体量权衡。

拦截器实现细节与执行顺序剖析

核心方法执行顺序

一个标准的拦截器需要实现HandlerInterceptor接口中的三个方法:

  • preHandle:在Controller方法执行前调用,返回true则放行,返回false则中断请求(此时可设置响应状态或跳转)。
  • postHandle:在Controller方法执行后、视图渲染前调用,可对ModelAndView进行二次加工。
  • afterCompletion:在整个请求完成后执行,适合用于资源清理、记录耗时。

执行顺序遵循“洋葱模型”:多个拦截器按注册顺序嵌套,preHandle按顺序正向执行,postHandle与afterCompletion按逆序执行,例如注册顺序为A、B,则流程为A.preHandle → B.preHandle → Controller → B.postHandle → A.postHandle → B.afterCompletion → A.afterCompletion。

配置时的常见误区与解决方案

  • 仅配置了`/,未排除静态资源,导致CSS、JS、图片被拦截,解决方案:在excludePathPatterns中添加/static//public//resources/,或直接在addInterceptors前通过registry.addInterceptor(…).excludePathPatterns(“/static/“)`。
  • 拦截器载入Service失败,原因:拦截器通过new创建,未被Spring容器管理,无法载入依赖,解决方案:将拦截器声明为@Component,然后在配置类中载入使用,如registry.addInterceptor(authInterceptor)。
  • 拦截器内操作HttpServletResponse导致跨域失效,若配置了CORS,需在定义跨域过滤器且拦截器preHandle中不要直接写死响应头,应通过CorsRegistry统一管理。

WebFlux (响应式)环境注意事项

在Spring WebFlux中,HandlerInterceptor不再适用,应使用WebFilter,如果项目计划从MVC迁移到WebFlux,拦截器逻辑需提前抽象成公共组件,以降低迁移成本。

西西云实战经验案例:基于Spring拦截器的API安全加固

在我们的一个电商客户项目中,其业务接口频繁被恶意调用,导致数据库压力骤增,我们结合西西云高防CDN与边缘计算节点,在Spring层面设计了双重拦截机制:

  • 第一层(应用内拦截器):自定义RateLimitInterceptor,基于HandlerMethod获取API类型,配合Redis实现IP+接口维度的滑动窗口限流,配置中仅对/order/和/pay/敏感路径启用,而非全局限流,保证高并发下正常接口零额外延迟。
  • 第二层(云端协同):拦截器检测到异常高频访问后,将风险IP上报至西西云防护策略库,由云端在边缘节点直接拦截恶意流量,极大减轻了源站压力

实现要点:在preHandle中通过request.getRequestURI()判断路径,若命中限流规则,直接设置响应码429并返回false,同时利用afterCompletion记录耗时数据,异步上报至监控系统,便于后续分析。这一方案帮助客户在业务峰值期间降低了95%的无效请求量

拦截器性能优化与异常处理最佳实践

减少preHandle中的耗时操作

preHandle执行时机在请求进入业务逻辑之前,若在其中调用远程接口、复杂数据库查询,会直接增加所有被拦截请求的响应时间,建议将耗时操作异步化,或引入本地缓存,如使用Caffeine存储黑名单IP。

Spring配置拦截器怎么做,Spring拦截器如何配置 第2张

正确处理异常

拦截器内抛出的异常不会进入@ControllerAdvice,为统一异常处理,推荐在拦截器中捕获后,通过response.sendError()或写入自定义错误码,并配合@ControllerAdvice中的ExceptionHandler兜底,更优雅的做法是在拦截器中不捕获异常,而使用HandlerInterceptor的afterCompletion做日志记录,并结合Spring MVC的全局异常解析器处理

静态资源彻底放行策略

  • 如果项目前后端分离,建议将静态资源交给Nginx/CDN处理,Spring仅需拦截/api/接口路径,从架构层面简化拦截器配置。
  • 如果必须由Spring处理,需使用/static/、/favicon.ico等精确前缀排除。

多环境配置差异化

在实际交付中,我们对开发、测试、生产环境使用不同的拦截规则,例如登录拦截器在开发环境仅对/front/生效,而生产环境需额外排除健康检查接口/actuator/health,通过Spring Profiles将excludePathPatterns配置外部化,有效隔绝了环境差异带来的误拦截风险

相关问答模块

拦截器与Filter有什么区别?在Spring项目中如何选择?

解答:Filter是Servlet规范中的组件,由Servlet容器管理,作用于所有请求(在DispatcherServlet之前),无法获取HandlerMethod信息,适合做字符编码、跨域、压缩、日志等粗粒度过滤,拦截器由Spring MVC管理,只能拦截经过DispatcherServlet的请求,可以拿到Controller方法对象,适合做业务相关的鉴权、参数校验、方法级别操作。推荐原则:通用性需求用Filter(如编码、CORS),业务性需求用拦截器(如权限、限流),注意二者执行顺序:Filter先于拦截器执行。

如果多个拦截器需要共享数据,如何传递?

解答:推荐使用request.setAttribute()方式在preHandle中传递数据,或通过ThreadLocal存储当前请求上下文,但由于连接池线程复用,必须在使用完毕后清理ThreadLocal,避免内存泄漏,更稳妥的方式是将数据放入HandlerInterceptor的preHandle返回的Model中,供postHandle和afterCompletion获取,若需跨线程共享,可借助RequestContextHolder,但不建议在异步请求中直接使用。


您的项目中是否遇到过拦截器放行、顺序或性能上的难题?欢迎在评论区留言,我们一起探讨解决方案,若您正在架构Spring微服务并希望云端防护与拦截器联动,也可以了解西西云的防护产品。

Spring配置拦截器怎么做,Spring拦截器如何配置 第3张

0