SpringBoot拦截器怎么用?从入门到实战的详细教程
作者:码农技术栈
还在为SpringMVC中的横切关注点发愁?本文用快递分拣的通俗类比,带你彻底搞懂拦截器的定位、执行流程和实战用法,从登录验证到日志记录,揭秘拦截器如何优雅处理请求,并对比过滤器差异,让你轻松掌握拦截器核心技巧
“从请求到响应的守门人——揭秘如何用拦截器优雅处理横切关注点”
一、拦截器定位图解
快递分拣中心类比解析:
拦截器就像快递分拣中心的质检流程,贯穿请求处理全链路:
- 客户端请求:快递包裹进入分拣中心
- 前置处理:检查包裹是否完好(如是否有破损、地址是否清晰)
- 控制器处理:按地址分拣到不同区域(处理具体业务逻辑)
- 后置处理:再次核对分拣结果(添加物流信息)
- 完成处理:包裹出库前的最终检查(记录处理日志)

二、拦截器 vs 过滤器
地铁安检 vs 小区门禁对比:
| 特性 | 拦截器(地铁安检) | 过滤器(小区门禁) |
|---|---|---|
| 管辖范围 | 只检查进站乘客(Spring MVC 路由) | 检查所有进出小区的人(所有请求) |
| 依赖关系 | 依赖地铁系统(Spring 上下文) | 独立于地铁(Servlet 容器) |
| 检查权限 | 能查乘客包里的地铁卡(@Autowired 获取 Bean) | 只能看身份证(需手动获取容器) |
| 检查时机 | 在候车厅前后(Controller 前后) | 在小区大门(Servlet 前后) |
| 典型场景 | 检查乘客是否携带违.禁.品(登录验证) | 登记所有访客信息(日志记录) |
三、三步实现拦截器
1. 创建拦截器类
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Autowired
private AuthService authService;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
// 认证逻辑
if (!authService.checkToken(request.getHeader("X-Token"))) {
response.sendError(401, "未授权");
return false; // 中断请求
}
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
// 可修改ModelAndView
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
// 资源清理
}
}
2. 注册拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/api/**")
.excludePathPatterns("/api/login");
}
}
3. 配置拦截路径
// 更精细的路径控制
registry.addInterceptor(new LogInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/static/**", "/error");
四、拦截器执行流程 🔄
快递包裹全流程质检图解:

核心步骤详解:
preHandle(前置检查):
像快递员检查包裹是否符合运输标准(如是否易燃易爆),返回 true 则继续处理,false 则直接拒绝(如未登录用户被拦截)。postHandle(后置核对):
分拣员按地址分拣后,质检人员再次核对目的地(如订单金额计算后添加折扣信息),可修改响应内容。afterCompletion(完成处理):
包裹出库后记录质检结果(如记录请求耗时、异常信息),即使中途出错也会执行(类似快递丢失后的追查记录)。
五、五大经典应用场景
1. 身份认证
public boolean preHandle(...) {
String token = request.getHeader("Authorization");
if(!jwtUtil.validateToken(token)) {
response.sendError(401);
return false;
}
return true;
}
2. 请求日志
public boolean preHandle(...) {
long startTime = System.currentTimeMillis();
request.setAttribute("startTime", startTime);
log.info("请求开始: {} {}", request.getMethod(), request.getRequestURI());
return true;
}
public void afterCompletion(...) {
long duration = System.currentTimeMillis() - (long)request.getAttribute("startTime");
log.info("请求完成: 耗时{}ms", duration);
}
3. 参数预处理
public boolean preHandle(...) {
if(request.getParameter("pageSize") == null) {
request.setAttribute("pageSize", 10);
}
return true;
}
4. 响应统一包装
public void postHandle(...) {
if(modelAndView != null) {
modelAndView.addObject("timestamp", System.currentTimeMillis());
}
}
5. 跨域支持
public boolean preHandle(...) {
response.setHeader("Access-Control-Allow-Origin", "*");
return true;
}
六、高级进阶技巧
1. 多拦截器顺序控制
registry.addInterceptor(i1).order(1); registry.addInterceptor(i2).order(2); // 数字越小优先级越高
2. 注解驱动拦截
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuditLog {}
// 拦截器判断
if (handler instanceof HandlerMethod) {
HandlerMethod hm = (HandlerMethod)handler;
if (hm.hasMethodAnnotation(AuditLog.class)) {
// 审计逻辑
}
}
3. 异常处理
public void afterCompletion(...) {
if(ex != null) {
metrics.increment("error." + ex.getClass().getSimpleName());
}
}
七、性能优化建议
- 轻量preHandle:前置处理尽量快速
- 异步处理:耗时操作放到afterCompletion
- 缓存验证结果:避免重复认证
- 合理排序:高频拦截器放前面
八、常见问题解答
Q1:拦截器能获取请求体吗?
A:可以,但需要包装Request重复读取:
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(request); byte[] body = wrapper.getContentAsByteArray();
Q2:如何跳过静态资源?
.excludePathPatterns("/static/**", "/favicon.ico")
Q3:拦截器vs切面怎么选?
- 拦截器:处理HTTP相关逻辑(头信息、参数等)
- 切面:处理业务逻辑(日志、事务等)
九、Spring Boot增强配置
# 控制拦截器顺序 spring.mvc.interceptor.order=0 # 开发环境打印拦截路径 logging.level.org.springframework.web.servlet.HandlerMapping=DEBUG
十、最新趋势展望
- WebFlux支持:响应式拦截器
- GraalVM适配:原生镜像中的优化
- AI集成:智能路由拦截
- 服务网格:与Istio等方案的协同
统计显示:企业级应用中平均每个项目使用3-5个拦截器
十一、总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
