在 Spring Boot(Spring MVC)中,多个拦截器会按配置顺序依次执行。其核心流程如下:
✅ 拦截器执行顺序(preHandle → controller → postHandle → afterCompletion)
按顺序执行 preHandle()
若所有 preHandle() 均返回 true
执行 Controller
执行 postHandle()(逆序)
执行 afterCompletion()(逆序)
📌 关键结论
如果:
那么执行流程如下:
拦截器 | preHandle | postHandle | afterCompletion |
|---|
Interceptor 1 | ✔️ 执行 | ❌ 不执行 | ✔️ 会执行 |
Interceptor 2 | ✔️ 执行 | ❌ 不执行 | ✔️ 会执行 |
👉 第一个拦截器的 afterCompletion() 一定会被执行。
sequenceDiagram
participant Client
participant Interceptor1
participant Interceptor2
participant Controller
Client ->> Interceptor1: preHandle() → true
Interceptor1 ->> Interceptor2: preHandle() → false
Note right of Interceptor2: 拦截请求<br/>不再继续后续流程
Interceptor2 ->> Interceptor1: afterCompletion()
Interceptor1 ->> Client: 返回响应sequenceDiagram
autonumber
participant Client
participant I1 as Interceptor 1
participant I2 as Interceptor 2
participant I3 as Interceptor 3
participant C as Controller
rect rgb(235, 248, 255)
Note over Client,C: 场景 A:全部通过
Client->>I1: preHandle() → true
I1->>I2: preHandle() → true
I2->>I3: preHandle() → true
I3->>C: 调用控制器方法
C-->>I3: 返回,I3.postHandle()
I3-->>I2: I2.postHandle()
I2-->>I1: I1.postHandle()
I1-->>I3: I3.afterCompletion()
I3-->>I2: I2.afterCompletion()
I2-->>I1: I1.afterCompletion()
I1-->>Client: 响应
end
rect rgb(255, 245, 230)
Note over Client,C: 场景 B:中途拦截(I2 返回 false)
Client->>I1: preHandle() → true
I1->>I2: preHandle() → false
Note right of I2: 终止调用链;不再调用 I3/Controller
I2-->>I1: I2.afterCompletion()
I1-->>Client: I1.afterCompletion() → 响应
end
rect rgb(255, 235, 238)
Note over Client,C: 场景 C:Controller 或渲染异常
Client->>I1: preHandle() → true
I1->>I2: preHandle() → true
I2->>I3: preHandle() → true
I3->>C: 调用控制器方法
C--x I3: 抛异常(或视图渲染异常)
Note right of I3: postHandle() 通常不执行
I3-->>I2: I3.afterCompletion()
I2-->>I1: I2.afterCompletion()
I1-->>Client: I1.afterCompletion() → 错误响应/全局异常处理
end