拦截器
约 694 字大约 2 分钟
2026-05-15
拦截器(Interceptor)是 Spring MVC 框架提供的 AOP 实现,用于在请求生命周期中注入通用逻辑,实现业务逻辑与通用功能的解耦。 它是一种动态拦截方法调用的机制,允许在 HTTP 请求到达 Controller 的前后、以及请求完成后执行预定义的代码。
主要用于解决 Web 应用中的通用性问题,例如身份认证、权限校验、日志记录、性能监控、请求参数预处理等。 例如,定义一个登录校验拦截器,在请求进入 Controller 前统一检查用户登录状态,若未携带有效令牌则直接拒绝访问并返回错误信息。
使用拦截器
在 Spring Boot 中使用拦截器,需要 定义 并 注册 拦截器。
1. 定义拦截器
创建一个新类,实现 HandlerInterceptor 接口,并根据需要重写其三个核心方法:
preHandle():在目标方法执行前调用。- 返回
true:放行,请求继续执行。 - 返回
false:中断请求,流程结束。
- 返回
postHandle():在目标方法执行后、视图渲染前调用,可修改返回的模型数据。afterCompletion():在整个请求处理完成后调用,通常用于资源清理,但只有当preHandle()成功执行并返回true后才会被执行。
下面是一个拦截器示例,并使用 @Component 注解将其注册为 Bean,方便后续注册。
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 拦截器逻辑
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
// ....
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
// 资源清理
}
}2. 注册配置拦截器
创建一个配置类,实现 WebMvcConfigurer 接口,并通过 addInterceptors() 方法注册拦截器,同时配置其拦截和放行的路径规则。
addPathPatterns():指定需要拦截的 URL 规则。excludePathPatterns():指定不需要拦截的 URL 规则(如静态资源、登录接口等)。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor) // 注册拦截器
.addPathPatterns("/**") // 拦截所有请求
.excludePathPatterns("/login", "/register", "/css/**", "/js/**"); // 放行特定路径
}
}路径匹配规则
/*: 匹配一级路径,如/user。/**: 匹配任意级路径,如/user/list。/book/*: 匹配/book下的一级路径。/book/**: 匹配/book下的任意级路径。
执行顺序
单个拦截器流程:preHandle() → Controller → postHandle() → afterCompletion()。
多个拦截器顺序:
preHandle()方法按配置顺序执行。postHandle()和afterCompletion()方法按配置的相反顺序执行。- 一旦某个拦截器的
preHandle()返回false,后续所有拦截器的postHandle()都不会执行,但已执行的preHandle()的afterCompletion()仍会执行。