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 的流程中!

相关推荐
Asthenia04128 分钟前
深入剖析 Java 中的 CompareTo 和 Equals 方法
后端
uhakadotcom23 分钟前
使用 Google Pay API 集成 Web 应用
后端
Asthenia041223 分钟前
为何在用 Netty 实现 Redis 服务时,要封装一个 BytesWrapper?
后端
来自星星的坤1 小时前
Spring Boot 邮件发送配置遇到的坑:解决 JavaMailSenderImpl 未找到的错误
java·开发语言·spring boot·后端·spring
uhakadotcom1 小时前
将游戏上传至 Steamworks 的简单步骤
后端·面试·github
慕瑾华1 小时前
Go语言的物联网
开发语言·后端·golang
lmryBC491 小时前
golang-defer延迟机制
开发语言·后端·golang
橘子青衫2 小时前
掌握HttpClient技术:从基础到实战(java.net.http)
java·后端·架构
uhakadotcom2 小时前
Google Play SDK 接入指南:一步步轻松集成
javascript·面试·github
冯韶雅2 小时前
Java语言的正则表达式
开发语言·后端·golang