Spring MVC 的源码流程解析

好问题 👍,Spring MVC 的源码流程其实就是一次 HTTP 请求在 DispatcherServlet 里的处理链路。这是面试和源码阅读里最常见的考点。我给你从整体架构 → 请求流程 → 源码关键点三个角度详细解析。


1. Spring MVC 架构核心

Spring MVC 的核心就是 前端控制器模式(Front Controller Pattern)

  • DispatcherServlet:所有请求的入口和出口(核心调度器)
  • HandlerMapping:找到请求对应的处理器(Controller + Method)
  • HandlerAdapter:调用处理器的适配器(反射调用方法)
  • Handler:也就是你写的 @Controller@RestController 方法
  • ViewResolver:找到视图解析器,把返回值解析成具体的视图或 JSON

2. 请求执行流程(高层)

以一个浏览器请求 /user/list 为例,完整链路大致如下:

请求进入 Tomcat → 
    DispatcherServlet.doDispatch()
        ① getHandler() → 找到 Handler(Controller 方法)
        ② getHandlerAdapter() → 找到对应适配器
        ③ 调用拦截器 preHandle()
        ④ handlerAdapter.handle() → 真正执行 Controller 方法
        ⑤ 处理返回结果(ModelAndView 或 ResponseBody)
        ⑥ 调用拦截器 postHandle()
        ⑦ resolveViewName() → 视图解析
        ⑧ 渲染视图
        ⑨ 调用拦截器 afterCompletion()
返回响应给客户端

3. 源码关键流程

(1) 请求入口:DispatcherServlet#doDispatch

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {
    HandlerExecutionChain mappedHandler = getHandler(request); // ① 找处理器
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // ② 找适配器
    if (!mappedHandler.applyPreHandle(request, response)) { return; } // ③ 执行拦截器前置逻辑
    ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler()); // ④ 调用处理器
    applyPostHandle(request, response, mv); // ⑤ 执行拦截器后置逻辑
    render(mv, request, response); // ⑥ 渲染视图
    triggerAfterCompletion(request, response, null); // ⑦ 拦截器完成回调
}

(2) 找 Handler:HandlerMapping

  • Spring MVC 会维护多个 HandlerMapping,常见的有:

    • RequestMappingHandlerMapping:处理 @RequestMapping 注解的方法
    • BeanNameUrlHandlerMapping:用 Bean 名字匹配 URL
  • 内部原理:
    启动时扫描所有 @Controller,把方法与 URL 映射关系放进 HandlerMethod 映射表。
    处理请求时,拿 URL 去查表,返回对应的 HandlerMethod


(3) 找 HandlerAdapter

不同类型的 Handler,需要不同的适配器来执行:

  • RequestMappingHandlerAdapter → 调用注解标注的 Controller 方法
  • SimpleControllerHandlerAdapter → 调用实现了 Controller 接口的类

重要: RequestMappingHandlerAdapter 内部还涉及到:

  • 参数解析器(HandlerMethodArgumentResolver)
    支持 @RequestParam@RequestBodyHttpServletRequest、自定义参数等
  • 返回值处理器(HandlerMethodReturnValueHandler)
    支持返回 StringModelAndView@ResponseBody JSON、ResponseEntity

(4) 执行 Controller 方法

HandlerAdapter 通过反射调用 HandlerMethod

  • 先解析参数(循环所有参数解析器,直到有一个支持该参数类型)
  • 再执行方法
  • 再根据返回值解析器处理结果

(5) 渲染结果

  • 如果返回的是 ModelAndView → 交给 ViewResolver 找视图(例如 JSP、Thymeleaf)
  • 如果返回的是 @ResponseBody → 用 HttpMessageConverter 转成 JSON / XML

常见的 HttpMessageConverter

  • MappingJackson2HttpMessageConverter(JSON)
  • StringHttpMessageConverter(字符串)
  • ByteArrayHttpMessageConverter(字节流)

(6) 拦截器链(HandlerInterceptor)

  • preHandle():在调用 Handler 前执行(可以中断请求)
  • postHandle():在 Handler 执行后,视图渲染前执行
  • afterCompletion():视图渲染后回调(异常也会调用)

相当于 Servlet 的过滤器(Filter),但更贴近 MVC。


4. 总结一句话

Spring MVC 的源码流程是:

请求进入 DispatcherServlet → 找到合适的 Handler 和适配器 → 执行拦截器 → 反射调用 Controller → 参数解析 + 返回值处理 → 视图解析 → 渲染响应 → 拦截器收尾。


posted @ 2025-09-04 12:29  juyss  阅读(20)  评论(0)    收藏  举报