1.1 拦截器定义与作用
想象一下你走进一栋办公楼,保安会在门口检查你的证件——这就是拦截器在SpringBoot中扮演的角色。拦截器(Interceptor)本质上是一种面向切面编程的实现,它允许你在请求到达控制器之前或之后执行特定操作。
拦截器的核心能力体现在三个关键时机点:preHandle在业务处理前执行,postHandle在业务处理后、视图渲染前执行,afterCompletion在整个请求完成后执行。这种设计让拦截器成为处理横切关注点的理想选择,比如权限验证、日志记录、性能监控这些需要贯穿多个接口的功能。
我记得去年参与的一个电商项目,当时需要在每个接口记录用户操作日志。如果每个控制器都写一遍日志代码,不仅重复劳动,后期维护更是噩梦。使用拦截器后,我们只需要在一个地方实现日志逻辑,所有接口自动获得这个能力。
1.2 拦截器与过滤器的区别
很多刚接触SpringBoot的开发人员会混淆拦截器和过滤器,它们确实都用于处理HTTP请求,但职责范围完全不同。
过滤器(Filter)属于Servlet规范,工作在更底层的网络层面。它能操作原始的Request和Response对象,功能更强大但也更重量级。拦截器则是Spring框架的产物,工作在应用层面,能够直接使用Spring的依赖注入和各种服务。

从执行顺序来看,过滤器永远最先执行,最后结束。拦截器的执行时机则与Spring的请求处理流程紧密绑定。过滤器能处理所有请求,包括静态资源;拦截器通常只针对Controller的请求。
有个很形象的比喻:过滤器像是海关,对所有进出口货物进行检查;拦截器更像是公司内部的门禁系统,只对进入办公区域的人员进行管理。
1.3 拦截器的应用场景
拦截器的应用场景几乎覆盖了Web开发的各个角落。权限验证是最典型的用例——在用户访问敏感接口前验证其登录状态和权限级别。日志记录同样重要,通过拦截器可以统一收集请求参数、响应时间、异常信息等关键数据。

性能监控也是拦截器的用武之地。我们可以在preHandle记录开始时间,在afterCompletion计算耗时,轻松实现接口性能分析。去年我们团队就靠这个功能发现了一个隐藏很深的性能瓶颈。
数据预处理同样适合使用拦截器。比如统一设置用户信息到ThreadLocal中,或者在所有响应头中添加特定的安全头。内容压缩、字符编码处理这些通用功能,用拦截器实现既优雅又高效。
拦截器的魅力在于,它让这些横跨整个系统的功能能够集中管理,避免了代码重复,也让业务逻辑保持纯净。这种设计确实极大地提升了代码的可维护性。 @Component public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String token = request.getHeader("Authorization");
if (!isValidToken(token)) {
response.setStatus(401);
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
// 可以在这里修改响应数据
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
// 清理资源或记录日志
}
}