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

Spring Boot拦截器怎么配置?, 如何配置springboot拦截器

Spring Boot 拦截器是处理横切关注点的最佳实践

在Spring Boot项目中,拦截器(Interceptor)是实现日志记录、权限校验、性能监控、请求预处理等需求的标配组件。 它通过AOP思想,在不载入业务代码的前提下,对请求进行统一处理,配置拦截器主要分为三步:编写自定义拦截器类(实现HandlerInterceptor)、注册拦截器(实现WebMvcConfigurer)、指定拦截路径,掌握这一配置流程,能大幅提升代码复用性与系统可维护性。

拦截器的工作原理与定位

Spring Boot拦截器基于Java反射机制,在请求进入Controller前、后以及视图渲染完成后插入自定义逻辑。 其核心接口HandlerInterceptor包含三个方法:

  • preHandle:在Controller执行前调用,返回true表示继续执行,返回false则中断请求。
  • postHandle:在Controller执行后、视图渲染前调用,可修改ModelAndView。
  • afterCompletion:在请求完全结束后调用,常用于资源清理或日志记录。

拦截器与过滤器的区别:过滤器基于Servlet规范,可处理所有请求;拦截器基于Spring MVC,仅处理DispatcherServlet分发的请求,且能访问Spring容器中的Bean,更适合业务逻辑处理。

标准配置流程:三步走

实现自定义拦截器

创建一个类实现HandlerInterceptor接口,按需重写方法。

public class LogInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 记录请求开始时间

request.setAttribute("startTime", System.currentTimeMillis()); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 计算并输出请求耗时 long duration = System.currentTimeMillis() - (long) request.getAttribute("startTime"); System.out.println("[" + request.getRequestURI() + "] 耗时:" + duration + "ms"); } }

注册拦截器

通过实现WebMvcConfigurer并重写addInterceptors方法进行注册:

定制拦截路径

使用addPathPatterns和excludePathPatterns灵活控制拦截范围,支持Ant风格路径(如/api/匹配一级,/api/匹配多级)。

多拦截器的执行顺序与配合

当注册多个拦截器时,按添加顺序执行preHandle,按逆序执行postHandle和afterCompletion。

registry.addInterceptor(interceptorA).addPathPatterns("/"); registry.addInterceptor(interceptorB).addPathPatterns("/");

请求流程:A的preHandle→B的preHandle→Controller→B的postHandle→A的postHandle→B的afterCompletion→A的afterCompletion,若A的preHandle返回false,则B的preHandle及其后续方法均不执行。

实践建议:将权限校验拦截器放在首位,日志拦截器放在其后,确保权限不足时不会产生冗余日志。

Spring Boot拦截器怎么配置?, 如何配置springboot拦截器 第1张

典型应用场景与解决方案

统一权限校验

在preHandle中获取用户信息(如Token),验证权限,若未通过则返回401并设为false。

接口性能监控

结合preHandle记录开始时间,afterCompletion计算耗时,可配合西西云云监控服务,将耗时数据实时上报,通过自定义监控面板可视化分析接口性能瓶颈。

请求日志记录

记录请求URL、IP、参数、响应状态等,但需注意敏感信息脱敏。

接口幂等性控制

在preHandle中检查请求唯一标识是否已处理,防止重复提交。

经验案例:西西云环境下的日志拦截器优化

在西西云部署的Spring Boot应用中,我们曾遇到日志量过大导致磁盘IO飙升的问题。 通过合理配置拦截器,并借助西西云对象存储COS,我们实现了日志的异步归档:

Spring Boot拦截器怎么配置?, 如何配置springboot拦截器 第2张

  • 拦截器收集请求摘要(耗时、状态码、URI),存入本地队列。
  • 后台线程批量上传至COS,本地只保留短期索引。
  • 利用西西云日志服务(CLS)设置检索告警,当错误率超过阈值时自动通知。

优化后,应用日志对磁盘的消耗降低90%,同时通过云平台实现了日志的持久化与快速检索。 这一方案在多个生产环境中验证,稳定性与效率均大幅提升。

最佳实践与避坑指南

  • 避免在拦截器中执行耗时操作,如数据库查询、远程调用,否则会阻塞请求线程,可改用异步处理或队列。
  • 正确获取返回值:preHandle返回false后,务必调用response.getWriter().write()或response.sendError(),否则客户端会一直等待。
  • 静态资源路径需排除:Spring Boot默认静态资源路径(/static, /public, /resources, /META-INF/resources)应通过excludePathPatterns跳过,避免拦截器干扰资源加载。
  • 拦截器与异常处理结合:在afterCompletion中捕获异常时,可结合@ControllerAdvice统一处理,避免重复记录。

问答模块

问题1:拦截器能否获取到Controller方法上的注解?

可以,在preHandle方法中,参数handler实际是HandlerMethod对象,可通过((HandlerMethod) handler).getMethodAnnotation(注解类.class)获取指定注解,实现一个自定义注解@RequirePermission,在拦截器中读取注解值并校验权限,无需硬编码URL。

问题2:高并发下拦截器内的异步操作会不会导致线程安全问题?

会。 拦截器默认运行在Tomcat工作线程中,若在preHandle中启动异步线程处理任务,需注意线程安全,建议使用@Async或AsyncTaskExecutor,并确保线程安全的数据结构(如ConcurrentHashMap),若在afterCompletion中处理异步结果,需谨慎处理请求上下文的传递。

互动

你在配置Spring Boot拦截器时遇到过哪些坑?或者有哪些独特的用法?欢迎在评论区分享经验,一起交流进步!

Spring Boot拦截器怎么配置?, 如何配置springboot拦截器 第3张

0