★ Spring MVC 请求处理全流程

结论先行:Spring MVC 以 DispatcherServlet(前端控制器) 为总入口。一次请求的完整调用:DispatcherServlet.doDispatch → HandlerMapping 根据 URL 找到 HandlerExecutionChain(处理器方法 + 拦截器链)→ HandlerAdapter 适配执行(参数解析器绑定入参、HttpMessageConverter 处理 @RequestBody)→ 执行 Controller 方法 → 返回结果由消息转换器写回或走 ViewResolver 渲染 → 过程异常交给 HandlerExceptionResolver → 最后拦截器 afterCompletion 收尾、响应返回。

一、关键步骤(按序)

  1. 请求到达 DispatcherServlet(继承 HttpServlet);
  2. HandlerMapping.getHandler:如 RequestMappingHandlerMapping 把 URL 映射到 HandlerMethod,并组装拦截器链;
  3. HandlerAdapter 选定:注解方法对应 RequestMappingHandlerAdapter;
  4. 执行拦截器 preHandle(任一返回 false 则中断);
  5. HandlerAdapter.handle:HandlerMethodArgumentResolver 解析 @PathVariable/@RequestParam/@RequestBody 等参数;
  6. 反射调用 Controller 方法,执行业务;
  7. 处理返回:@ResponseBody → HttpMessageConverter 序列化写回;返回视图名 → ViewResolver 解析、渲染 ModelAndView;
  8. 拦截器 postHandle(渲染前);
  9. 异常处理:Controller 抛出的异常经 HandlerExceptionResolver(@ExceptionHandler / @ControllerAdvice)统一处理;
  10. 拦截器 afterCompletion(无论成败都执行),响应返回。
@RestController
@RequestMapping("/orders")
public class OrderController {
    @GetMapping("/{id}")                     // 步骤 2:被映射为 HandlerMethod
    public Order detail(@PathVariable Long id) {   // 步骤 5:参数解析器取路径变量
        return orderService.get(id);         // 步骤 7:@ResponseBody → JSON 写回
    }
}

二、关键组件一句话

组件职责
DispatcherServlet前端控制器,调度一切
HandlerMappingURL → Handler + 拦截器链
HandlerAdapter屏蔽 handler 类型差异,统一调用
HandlerMethodArgumentResolver方法参数绑定
HttpMessageConverter@RequestBody/@ResponseBody 消息转换(JSON 等)
HandlerExceptionResolver统一异常出口
ViewResolver视图名 → View

常见追问 / 记忆点

  • 追问 1:为什么需要 HandlerAdapter?答:让 DispatcherServlet 不感知 handler 具体类型(注解方法、Controller 接口、HttpRequestHandler 都能被适配调用),便于扩展。
  • 追问 2:@ResponseBody 与 ModelAndView 路径区别?答:前者在 HandlerAdapter 内由消息转换器直接写响应(ModelAndView 为 null),后者走 ViewResolver 渲染。
  • 追问 3:拦截器三个方法的执行时机?答:preHandle 在 Controller 前,postHandle 在渲染前,afterCompletion 在请求完成后。
  • 记忆点:链路口诀——"调度找映射,映射出链,适配执行,异常处理器兜底,转换器/视图收尾"。
笔记加载中…