Spring拦截器(Interceptor)学习笔记
一、拦截器概述
1.1 什么是拦截器?
拦截器是Spring框架提供的一种动态拦截方法调用的机制,类似于Servlet中的过滤器(Filter)。主要特点包括:
- 动态拦截控制器方法的执行
- 在指定方法调用前后执行预设代码
- 用于处理通用性的业务逻辑(如登录校验、权限检查、日志记录等)
1.2 拦截器 vs 过滤器
| 特性 |
拦截器(Interceptor) |
过滤器(Filter) |
| 所属框架 |
Spring MVC |
Servlet规范 |
| 拦截范围 |
只拦截Spring环境中的资源 |
拦截所有资源 |
| 依赖 |
依赖Spring容器 |
不依赖任何框架 |
| 执行时机 |
Controller方法前后 |
Servlet处理前后 |
| 实现接口 |
HandlerInterceptor |
Filter |
二、拦截器快速入门
2.1 实现步骤
- 定义拦截器:实现
HandlerInterceptor接口
- 注册配置:通过
WebMvcConfigurer配置
2.2 代码实现
1) 自定义拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Component public class DemoInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle执行..."); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle执行..."); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion执行..."); } }
|
2) 注册拦截器
1 2 3 4 5 6 7 8 9 10 11 12
| @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private DemoInterceptor demoInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(demoInterceptor) .addPathPatterns("/**"); } }
|
2.3 执行顺序验证
当访问一个Controller方法时,控制台输出:
1 2 3 4
| preHandle执行... Controller方法执行... postHandle执行... afterCompletion执行...
|
注意:如果preHandle返回false,则后续流程都不会执行!
三、登录校验拦截器实战
3.1 令牌校验实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| @Slf4j @Component public class TokenInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String url = request.getRequestURL().toString(); if(url.contains("login")) { log.info("登录请求,放行"); return true; } String jwt = request.getHeader("token"); if(!StringUtils.hasLength(jwt)) { log.error("令牌为空"); response.setStatus(HttpStatus.SC_UNAUTHORIZED); return false; } try { JwtUtils.parseJWT(jwt); } catch (Exception e) { log.error("令牌解析失败"); response.setStatus(HttpStatus.SC_UNAUTHORIZED); return false; } log.info("令牌校验通过"); return true; } }
|
3.2 配置拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private TokenInterceptor tokenInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(tokenInterceptor) .addPathPatterns("/**") .excludePathPatterns("/login"); } }
|
四、拦截器详解
4.1 拦截路径配置
1) 基本配置方法
addPathPatterns():添加拦截路径
excludePathPatterns():添加排除路径
1 2 3
| registry.addInterceptor(interceptor) .addPathPatterns("/**") .excludePathPatterns("/login");
|
2) 常见路径模式
| 模式 |
说明 |
/* |
一级路径(如/user) |
/** |
任意级路径(如/user/1) |
/admin/** |
拦截/admin下的所有路径 |
/secure/*.do |
拦截/secure下的所有.do请求 |
4.2 拦截器执行流程
完整请求生命周期
- 过滤器前置处理
- DispatcherServlet接收请求
- 拦截器preHandle
- Controller方法执行
- 拦截器postHandle
- 视图渲染
- 拦截器afterCompletion
- 过滤器后置处理
执行流程图

五、最佳实践建议
登录校验:推荐使用拦截器而非过滤器
- 能利用Spring的依赖注入
- 更精准控制Spring环境中的请求
路径配置:
1 2 3 4
| registry.addInterceptor(authInterceptor) .addPathPatterns("/api/**") .excludePathPatterns("/api/public/**");
|
性能优化:
- 在
preHandle中进行轻量级检查
- 避免在拦截器中执行耗时操作
多拦截器顺序:
1 2
| registry.addInterceptor(interceptor1).order(1); registry.addInterceptor(interceptor2).order(2);
|
六、常见问题解答
Q1:拦截器和过滤器如何选择?
- 需要处理Spring相关功能(如自动注入、AOP等)→ 拦截器
- 需要处理静态资源、非Spring请求 → 过滤器
Q2:拦截器能获取Controller方法信息吗?
可以,通过handler参数:
1 2 3 4 5
| if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); }
|
Q3:拦截器中如何修改响应数据?
可以在postHandle中操作ModelAndView:
1 2 3 4
| @Override public void postHandle(...) { modelAndView.addObject("newData", "value"); }
|