08-Spring MVC 请求处理流程全解析

Spring MVC 请求处理流程全解析(从 DispatcherServlet 到 Controller)

Spring MVC 是构建 Web 应用的基础框架,而其中最核心的组件就是 DispatcherServlet,它作为整个请求流程的入口和协调者,掌控了从接收请求、分发到处理器再到视图渲染的全过程。本文将从源码出发,深入剖析 Spring MVC 的请求处理流程。


一、核心架构概览

请求从浏览器发起到 Controller 方法执行,Spring MVC 的核心流程如下:

复制代码
客户端请求 → DispatcherServlet → HandlerMapping → HandlerAdapter → Controller → ViewResolver → 渲染视图

简要组件说明:

组件 作用
DispatcherServlet 中央调度器,拦截所有请求
HandlerMapping 根据请求路径查找处理器(Controller)
HandlerAdapter 适配执行不同类型的处理器
Controller 具体的业务处理逻辑
ViewResolver 将逻辑视图名称解析为物理视图
View 渲染返回结果(如 JSP, Thymeleaf 等)

二、DispatcherServlet 初始化过程

DispatcherServlet 是一个 HttpServlet,其初始化发生在容器启动时的 init() 方法中。

源码路径:org.springframework.web.servlet.DispatcherServlet

java 复制代码
@Override
protected void onRefresh(ApplicationContext context) {
    initStrategies(context); // 初始化 9 大组件
}

其中包括:

  • initHandlerMappings()
  • initHandlerAdapters()
  • initViewResolvers()

✅ Spring 提前准备好请求处理相关的全部组件,等待请求到来。


三、请求到达 DispatcherServlet 的处理流程

java 复制代码
@Override
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 1. 根据请求找到 HandlerExecutionChain(含拦截器)
    HandlerExecutionChain mappedHandler = getHandler(processedRequest);

    // 2. 根据 Handler 查找合适的 HandlerAdapter
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

    // 3. 执行 Controller 方法
    ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

    // 4. 解析视图
    View view = resolveViewName(mv.getViewName(), mv.getModel(), ...);

    // 5. 渲染视图
    view.render(mv.getModel(), request, response);
}

🌟 小提示:

如果使用的是 @RequestMapping 注解的 Controller,最终的 Handler 是 RequestMappingHandlerAdapter


四、HandlerMapping 详解

Spring MVC 提供了多种 HandlerMapping,常见的是:

  • RequestMappingHandlerMapping(@RequestMapping)
  • SimpleUrlHandlerMapping(传统 XML)

它的作用是根据请求路径、方法等信息,找到具体的 Controller 和方法。

java 复制代码
@Override
public HandlerExecutionChain getHandler(HttpServletRequest request) {
    for (HandlerMapping hm : this.handlerMappings) {
        HandlerExecutionChain handler = hm.getHandler(request);
        if (handler != null) {
            return handler;
        }
    }
}

五、HandlerAdapter 的职责

由于处理器类型不一(注解 Controller、HttpRequestHandler、Servlet 等),需要适配器模式将其统一执行。

常用的 HandlerAdapter:

  • RequestMappingHandlerAdapter
  • SimpleControllerHandlerAdapter
java 复制代码
@Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) {
    // 实际调用 Controller 中的方法
    invokeHandlerMethod(...);
}

六、ViewResolver 与视图渲染

根据 ModelAndView 中的逻辑视图名,调用 ViewResolver 解析成物理视图地址,再进行渲染。

如 Thymeleaf:

java 复制代码
InternalResourceViewResolver --> /WEB-INF/views/login.html

视图最终调用 View#render() 完成页面展示。


七、流程总结图

sql 复制代码
HTTP 请求
   ↓
DispatcherServlet
   ↓
HandlerMapping(匹配 Controller)
   ↓
HandlerAdapter(调用 Controller)
   ↓
执行方法,返回 ModelAndView
   ↓
ViewResolver(解析视图)
   ↓
View(渲染视图)
   ↓
HTTP 响应

八、嵌入式问答(结合源码场景)

💬 Q:DispatcherServlet 默认会处理哪些 URL?

🧠 A:默认会拦截 / 下的所有请求。可以通过 Web 配置自定义其映射路径。


💬 Q:如果 Controller 方法返回 String,会发生什么?

🧠 A:返回的字符串会作为视图名交由 ViewResolver 处理,找到对应的页面进行渲染。


💬 Q:请求参数是如何绑定到方法参数上的?

🧠 A:通过 HandlerMethodArgumentResolver 实现参数的解析和注入,比如 @RequestParam@PathVariable 对应的解析器。


💬 Q:404 一般在哪个阶段出现?

🧠 A:大概率出现在 HandlerMapping 阶段,未匹配到 Controller 方法。


九、总结

Spring MVC 请求处理流程是高度解耦的链式结构,核心是 DispatcherServlet。通过一系列组件协同工作完成请求的接收、处理和响应。

掌握 DispatcherServlet 的执行过程有助于我们理解:

  • 为什么请求找不到 Controller?
  • 为什么参数没注入成功?
  • 为什么页面渲染失败?

✅ 一切都在 DispatcherServlet 的流程中!

相关推荐
沐怡旸25 分钟前
【底层机制】右值引用是什么?为什么要引入右值引用?
c++·面试
努力的小郑34 分钟前
MySQL索引(三):字符串索引优化之前缀索引
后端·mysql·性能优化
IT_陈寒1 小时前
🔥3分钟掌握JavaScript性能优化:从V8引擎原理到5个实战提速技巧
前端·人工智能·后端
前端小巷子1 小时前
JS 打造丝滑手风琴
前端·javascript·面试
程序员清风2 小时前
贝壳一面:年轻代回收频率太高,如何定位?
java·后端·面试
考虑考虑2 小时前
Java实现字节转bcd编码
java·后端·java ee
AAA修煤气灶刘哥2 小时前
ES 聚合爽到飞起!从分桶到 Java 实操,再也不用翻烂文档
后端·elasticsearch·面试
小高0072 小时前
🚨 2025 最该淘汰的 10 个前端 API!
前端·javascript·面试
大厂码农老A2 小时前
面试官:“聊聊你最复杂的项目?” 为什么90%的候选人第一句就栽了?
java·面试
爱读源码的大都督2 小时前
Java已死?别慌,看我如何用Java手写一个Qwen Code Agent,拯救Java
java·人工智能·后端