拦截器

下面给你一套 Spring 自定义拦截器的完整流程 + 图解式理解,非常适合真实项目使用。


✅ 一句话理解拦截器

拦截器是 Spring MVC 请求执行链上的钩子,
用于在 Controller 调用前后,执行额外逻辑:

✔ 登录校验
✔ 权限验证
✔ 日志记录
✔ 鉴权 token 解析
✔ 统计请求耗时



🔵 自定义拦截器的完整流程(4 步走)


✔ 第 1 步:定义拦截器类

👉 继承 HandlerInterceptor

最常用三个回调:

🟦 1. preHandle() (请求到 Controller 之前执行)

适合登录校验、权限验证

🟨 2. postHandle() (Controller 执行后,视图渲染前)

适合:日志、修改 Model 数据

🟩 3. afterCompletion() (整个请求完成后执行)

适合:资源回收、性能分析

📌 示例:

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
public class LoginInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("user");
if(user == null){
System.out.println("未登录,拒绝访问");
response.sendRedirect("/login");
return false; // 拦截
}
System.out.println("通过拦截");
return true; // 放行
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) {
System.out.println("Controller 执行完了");
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
System.out.println("请求结束,资源清理");
}
}


✔ 第 2 步:在配置类中注册拦截器

实现 WebMvcConfigurer

1
2
3
4
5
6
7
8
9
10
@Configuration
public class WebConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") // 拦截所有请求
.excludePathPatterns("/login", "/register", "/static/**"); // 放行路径
}
}

🔹 这里就是建立关系:
「哪些请求会经过我的拦截器」



✔ 第 3 步:拦截器加入 Spring MVC 执行链

🌍 请求过来后执行顺序如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
请求进入

DispatcherServlet(分发器)

HandlerInterceptor.preHandle() —— 拦截器链前置执行

Controller —— 执行业务方法

HandlerInterceptor.postHandle() —— 拦截器链后置执行

ViewResolver —— 渲染视图

HandlerInterceptor.afterCompletion() —— 请求完成清理

返回响应

👉 图形理解:

1
--- preHandle ---> Controller --- postHandle ---> View --- afterCompletion ---


✔ 第 4 步:Spring 按链式顺序调用多个拦截器

多个拦截器执行顺序像洋葱模型:

📌 执行顺序

1
2
3
多个拦截器的 preHandle() 按注册顺序执行
多个拦截器的 postHandle() 按逆序执行
多个拦截器的 afterCompletion() 按逆序执行

📍 示例:

注册:

1
2
registry.addInterceptor(A);
registry.addInterceptor(B);

执行顺序:

1
A.pre → B.pre → Controller → B.post → A.post → B.after → A.after


🔶 总体流程示意图(记住这个就清晰了)

1
2
3
4
5
6
7
8
9
   preHandle()

controller()

postHandle()

视图渲染

afterCompletion()


🔴 拦截器的常见用途

✔ 登录检查
✔ JWT 解析 + 用户上下文绑定
✔ 访问日志
✔ 请求限流
✔ 请求计时
✔ 权限权限控制
✔ 统一处理跨域



🟩 和 Filter / AOP 的区别

名称 作用层级 场景
Filter Servlet 层 比如编码、XSS 过滤
Interceptor Spring MVC 层 登录鉴权、日志
AOP 业务方法层 性能监控、事务、日志


✨ 最后给你一个最佳实践模板

实际项目中你可以这样用:

1️⃣ ThreadLocal存储登录用户(ThreadLocal)

(你的系统里 ThreadLocal 用来存用户就行)

2️⃣ 拦截器中解析 token

(你已经在项目写过 token 解析逻辑)

3️⃣ afterCompletion 里清理 ThreadLocal

(防止内存泄漏)