spring mvc 执行流程
当然可以!以下是完整的 Spring MVC 请求-响应执行流程,涵盖了包括 HandlerInterceptor
、RequestBodyAdvice
、ResponseBodyAdvice
、异常处理等组件的完整生命周期。
✅ Spring MVC 执行流程总览图(重点组件标注)
+---------------------+
| DispatcherServlet |
+---------------------+
|
v
+---------------------+
| HandlerMapping 查找 |
+---------------------+
|
v
+-------------------------------+
| HandlerInterceptor.preHandle |
+-------------------------------+
|
v
+--------------------------------------------+
| 参数解析(HandlerMethodArgumentResolver) |
| - 如果参数有 @RequestBody: |
| → RequestBodyAdvice.beforeBodyRead() |
| → HttpMessageConverter 反序列化 |
| → RequestBodyAdvice.afterBodyRead() |
+--------------------------------------------+
|
v
+---------------------+
| Controller 方法 |
+---------------------+
|
v
+------------------------------+
| 返回值处理(HandlerAdapter) |
+------------------------------+
|
v
+--------------------------------------+
| 如果返回 @ResponseBody 或 @RestController: |
| → ResponseBodyAdvice.beforeBodyWrite() |
| → HttpMessageConverter 序列化成 JSON/XML |
+--------------------------------------+
|
v
+-------------------------------+
| HandlerInterceptor.postHandle |
+-------------------------------+
|
v
+------------------------------+
| 写入响应(response 输出) |
+------------------------------+
|
v
+---------------------------------+
| HandlerInterceptor.afterCompletion |
+---------------------------------+
📘 对每个关键组件的简述
1️⃣ HandlerInterceptor
preHandle()
: 请求进入 Controller 之前执行,可以中断请求。postHandle()
: Controller 正常执行完 但在视图渲染之前。afterCompletion()
: 整个请求完成后执行(无论是否抛出异常)。
2️⃣ RequestBodyAdvice
- 作用于
@RequestBody
参数。 beforeBodyRead()
:请求体还未读,可包裹 InputStream 做解密等。afterBodyRead()
:反序列化后,对 Java 对象进行处理或验证。handleEmptyBody()
:请求体为空时的处理。
3️⃣ ResponseBodyAdvice
- 作用于
@ResponseBody
返回值。 beforeBodyWrite()
:在响应写入 body 之前,统一包装、脱敏等操作。
4️⃣ ExceptionHandler
/ @ControllerAdvice
- 如果上面任何阶段抛出异常,会进入全局异常处理。
- 比如
@ExceptionHandler(Exception.class)
或@RestControllerAdvice
。
🧠 一个典型请求流程中的关键点
假设你有如下 Controller:
@RestController
public class UserController {
@PostMapping("/user")
public CommonResponse<UserDTO> createUser(@RequestBody EncryptedRequest request) {
return CommonResponse.success(request.getUser());
}
}
-
请求进入,先执行
HandlerInterceptor.preHandle()
。 -
Spring 解析参数时发现是
@RequestBody
:- 执行
RequestBodyAdvice.beforeBodyRead()
解密。 - 使用 HttpMessageConverter 反序列化 JSON。
- 执行
RequestBodyAdvice.afterBodyRead()
做校验或填充。
- 执行
-
执行
createUser()
方法。 -
返回结果进入
ResponseBodyAdvice.beforeBodyWrite()
包装为统一结构。 -
使用 HttpMessageConverter 写出 JSON 响应。
-
执行
HandlerInterceptor.postHandle()
和afterCompletion()
。
🔍 加分项:异常时流程
如果中途(如参数验证、方法执行)抛出异常:
-
DispatcherServlet 捕获异常;
-
检查是否有
@ExceptionHandler
/@ControllerAdvice
; -
如果异常处理方法返回对象带
@ResponseBody
:- 也会走
ResponseBodyAdvice.beforeBodyWrite()
; - 再写入响应。
- 也会走
需要我根据这个流程画一个图(比如时序图或流程图)也可以告诉我。是否要补充 Servlet Filter、AOP 位置等?