Spring MVC 运行流程
Spring MVC 将所有的请求都提交给
DispatcherServlet,它会委托应用系统的其他模块负责对请求进行真正的处理工作。DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的 Controller.DispatcherServlet请求提交到目标 ControllerController 进行业务逻辑处理后,会返回一个
ModelAndViewDispatcher 查询一个或多个
ViewResolver视图解析器,找到ModelAndView对象指定的视图对象视图对象负责渲染返回给客户端。
六步主线是经典 MVC 视图渲染路径,但现代 REST 接口早已不走 ViewResolver(直接写 JSON),且主线之外还有四个关键环节常被遗漏:过滤器/拦截器链、参数解析与返回值处理、异常解析、异步处理。本文补成完整请求生命周期。
完整请求生命周期
- 容器接收:Servlet 容器(Tomcat)把请求交给 DispatcherServlet(前端控制器,url-pattern / 或 /api/*)
- 过滤器链:先过 Filter(CharacterEncoding、Security、CORS 等 Servlet 级过滤器),与 Spring 无关的容器设施
- 拦截器前置:HandlerInterceptor.preHandle(鉴权、日志、限流——Spring 级 AOP 之前的钩子)
- HandlerMapping:按 URL/方法注解匹配 Handler(Controller 方法),并组装拦截器链 + Handler 为 HandlerExecutionChain
- HandlerAdapter 适配:DispatcherServlet 不直接调 Handler,而是找支持该 Handler 类型的适配器(RequestMappingHandlerAdapter)——适配器模式隔离调用差异
- 参数解析:适配器驱动 ArgumentResolver 把请求加工成方法入参:@PathVariable/@RequestParam/@RequestBody(HttpMessageConverter 反序列化 JSON)/自定义解析器
- 执行业务:Controller 方法运行(事务/AOP 在此层生效)
- 返回值处理:ReturnValueHandler 处理返回:@ResponseBody → HttpMessageConverter 序列化 JSON 直接写响应(REST 路径到此结束,无视图);否则封装 ModelAndView
- 拦截器后置:postHandle(仅同步流程)
- 视图渲染(仅 MVC 视图路径):ViewResolver 解析逻辑视图名 → View 渲染模型 → 响应 HTML
- afterCompletion:拦截器收尾(资源清理、耗时统计),异常也会走到
- 异常分支:任意环节抛异常 → HandlerExceptionResolver 链处理(@ExceptionHandler/@ControllerAdvice/默认错误页),处理后仍走渲染或 JSON 错误响应
关键组件职责速查
| 组件 | 职责 | 扩展点 |
|---|---|---|
| DispatcherServlet | 总调度 | 一般不扩展 |
| HandlerMapping | URL→Handler | 自定义映射(如数据库路由) |
| HandlerAdapter | 调用 Handler | 支持新 Handler 类型 |
| ArgumentResolver | 请求→入参 | 自定义注解参数(如 @LoginUser) |
| HttpMessageConverter | 字节↔对象 | Jackson 配置、加 Protobuf |
| ReturnValueHandler | 返回→响应 | 统一响应包装 |
| HandlerExceptionResolver | 异常→错误响应 | @ControllerAdvice 全局异常 |
| ViewResolver | 逻辑名→View | REST 项目基本不用 |
| HandlerInterceptor | 前后钩子 | 鉴权/埋点/租户上下文 |
REST 时代的流程简化
前后端分离项目中,@RestController = @Controller + @ResponseBody:流程在步骤 8 直接写 JSON 返回,ViewResolver/View 完全退场。理解这点能解释”为什么我的项目里没有视图解析器配置也能跑”。
拦截器 vs 过滤器 vs AOP
- Filter:Servlet 规范,容器级,拿不到 Spring 上下文细节(但可注入 bean),管编码/安全/CORS
- Interceptor:Spring MVC 级,能拿 Handler 信息,管请求级横切(鉴权、上下文)
- AOP:方法级,管业务方法横切(事务、日志)
三者作用层次递进:进容器 → 进 MVC → 进方法。
异步请求分支
Handler 返回 Callable/DeferredResult/WebFlux 流时:DispatcherServlet 启动异步(request.startAsync),容器线程释放,业务在独立线程完成后回调恢复 MVC 流程(重新走适配器与返回值处理)。拦截器的 afterConcurrentHandlingStarted 在此分支触发——高并发长任务接口的吞吐关键。
六步主线是骨架,四大补充环节(过滤/拦截、参数与返回值、异常、异步)才是真实请求的完整血肉;REST 项目记住”步骤 8 即终点”,视图相关组件即可安心忽略。













