Spring 机制六: MVC 全链路源码解析:从 DispatcherServlet 到返回值解析(超硬核源码深度)

复制代码
博主社群介绍: ① 群内初中生、高中生、本科生、研究生、博士生遍布,可互相学习,交流困惑。
② 热榜top10的常客也在群里,也有数不清的万粉大佬,可以交流写作技巧,上榜经验,涨粉秘籍。
③ 群内也有职场精英,大厂大佬,跨国企业主管,可交流技术、面试、找工作的经验。
进群免费赠送写作秘籍一份,助你由写作小白晋升为创作大佬,进群赠送CSDN评论防封脚本,送真活跃粉丝,助你提升文章热度。
群公告里还有全网大赛约稿汇总/博客提效工具集/CSDN自动化运营脚本 有兴趣的加文末联系方式,备注自己的CSDN昵称,拉你进群,互相学习共同进步。

文章目录

  • [Spring 机制六: MVC 全链路源码解析:从 DispatcherServlet 到返回值解析(超硬核源码深度)](#Spring 机制六: MVC 全链路源码解析:从 DispatcherServlet 到返回值解析(超硬核源码深度))
  • [1. Spring MVC 架构与整体链路总览](#1. Spring MVC 架构与整体链路总览)
  • [2. DispatcherServlet 初始化流程(源码解析)](#2. DispatcherServlet 初始化流程(源码解析))
  • [3. 请求分发核心:doDispatch](#3. 请求分发核心:doDispatch)
  • [4. HandlerMapping:如何找到 Controller?](#4. HandlerMapping:如何找到 Controller?)
    • [RequestMappingHandlerMapping 工作流程](#RequestMappingHandlerMapping 工作流程)
  • [5. HandlerAdapter:如何调用 Controller 方法?](#5. HandlerAdapter:如何调用 Controller 方法?)
    • [HandlerAdapter 调用链源码](#HandlerAdapter 调用链源码)
  • [6. 参数解析器(ArgumentResolver)内部原理](#6. 参数解析器(ArgumentResolver)内部原理)
  • [7. 返回值处理器(ReturnValueHandler)链路](#7. 返回值处理器(ReturnValueHandler)链路)
  • [8. 拦截器执行顺序](#8. 拦截器执行顺序)
  • [9. Controller 调用链全景图](#9. Controller 调用链全景图)
  • [10. Spring MVC 与 AOP 如何协作](#10. Spring MVC 与 AOP 如何协作)
  • [11. 实战:自定义参数解析器](#11. 实战:自定义参数解析器)
  • [12. 超级总图:Spring MVC 全链路流程图](#12. 超级总图:Spring MVC 全链路流程图)
  • [13. 参考文档](#13. 参考文档)
  • 结束语

Spring 机制六: MVC 全链路源码解析:从 DispatcherServlet 到返回值解析(超硬核源码深度)

目录

  1. Spring MVC 的整体架构与执行链路总览
  2. DispatcherServlet 初始化流程(源码)
  3. 请求分发核心:doDispatch 全链路解析
  4. HandlerMapping 的查找过程
  5. HandlerAdapter 的适配与调用
  6. 参数解析器(Argument Resolver)内部原理
  7. 返回值处理器(ReturnValueHandler)链路
  8. 拦截器执行顺序
  9. Controller 方法调用链全景图(Mermaid)
  10. 与 AOP 如何协同
  11. 实战:自定义参数解析器
  12. Mermaid 超级总图:从请求进入到响应输出
  13. 参考文档

1. Spring MVC 架构与整体链路总览

Spring MVC 的核心处理流程可以抽象为:

HTTP 输入 → DispatcherServlet → HandlerMapping → HandlerAdapter → 参数解析 → 调用 Controller 方法 → 返回值解析 → 视图解析 → HTTP 输出

整体流程 Mermaid 展示:
找到 Handler HTTP 请求 DispatcherServlet HandlerMapping HandlerMethod HandlerAdapter 参数解析 ArgumentResolver 调用目标方法 返回结果 ReturnValueHandler ViewResolver 渲染视图 HTTP Response


2. DispatcherServlet 初始化流程(源码解析)

DispatcherServlet 是 Spring MVC 核心入口点,继承链:

复制代码
FrameworkServlet → HttpServletBean → HttpServlet

DispatcherServlet#onRefresh

java 复制代码
@Override
protected void onRefresh(ApplicationContext context) {
    initStrategies(context);
}

initStrategies 装配 MVC 全套组件

java 复制代码
protected void initStrategies(ApplicationContext context) {
    initMultipartResolver(context);
    initLocaleResolver(context);
    initThemeResolver(context);
    initHandlerMappings(context);
    initHandlerAdapters(context);
    initHandlerExceptionResolvers(context);
    initRequestToViewNameTranslator(context);
    initViewResolvers(context);
}

重点:

  • HandlerMapping
  • HandlerAdapter
  • ViewResolver

都是在这里完成自动装配,属于 MVC 的"预热阶段"。


3. 请求分发核心:doDispatch

核心路径:

复制代码
FrameworkServlet#doService → DispatcherServlet#doDispatch

简化源码:

java 复制代码
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());
    mappedHandler.applyPostHandle(request, response, mv);
    processDispatchResult(request, response, mappedHandler, mv);
}

4. HandlerMapping:如何找到 Controller?

职责:

根据 URL 找到对应 Controller 的 HandlerMethod

常见 HandlerMapping:

类型 用途
RequestMappingHandlerMapping 处理 @RequestMapping 体系
BeanNameUrlHandlerMapping Bean 名称即 URL
SimpleUrlHandlerMapping XML 配置 URL

Spring Boot 默认使用 RequestMappingHandlerMapping。

RequestMappingHandlerMapping 工作流程

启动时扫描所有 @Controller/@RestController + @RequestMapping 方法,构建:

复制代码
Map<RequestMappingInfo, HandlerMethod>

请求时执行:

java 复制代码
public HandlerExecutionChain getHandler(HttpServletRequest request) {
    return this.mappingRegistry.getMappings().entrySet().stream()
        .filter(entry -> entry.getKey().getPatternsCondition().match(request))
        .findFirst()
        .map(entry -> new HandlerExecutionChain(entry.getValue()))
        .orElse(null);
}

5. HandlerAdapter:如何调用 Controller 方法?

Spring MVC 支持多种 HandlerAdapter:

Adapter 用途
RequestMappingHandlerAdapter 注解 Controller 方法调用
HttpRequestHandlerAdapter 支持 HttpRequestHandler
SimpleControllerHandlerAdapter 早期 Controller 模式

默认使用 RequestMappingHandlerAdapter,负责:

  • 参数绑定
  • 参数解析器链
  • 返回值解析器链
  • 调用 HandlerMethod

HandlerAdapter 调用链源码

java 复制代码
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) {
    return invokeHandlerMethod(request, response, (HandlerMethod) handler);
}

6. 参数解析器(ArgumentResolver)内部原理

核心类:HandlerMethodArgumentResolverComposite

流程:

java 复制代码
for each parameter:
    1. 找到 supportsParameter=true 的 resolver
    2. 调用 resolver.resolveArgument()

常见解析器:

解析器 用途
RequestParamMethodArgumentResolver @RequestParam
PathVariableMethodArgumentResolver @PathVariable
RequestResponseBodyMethodProcessor @RequestBody
ServletRequestMethodArgumentResolver HttpServletRequest

源码执行:

java 复制代码
public Object resolveArgument(...) {
    HandlerMethodArgumentResolver resolver = getResolver(parameter);
    return resolver.resolveArgument(parameter, mavContainer, request, binderFactory);
}

7. 返回值处理器(ReturnValueHandler)链路

控制器方法返回值交给 HandlerMethodReturnValueHandlerComposite

常见解析器:

类型 用途
RequestResponseBodyMethodProcessor @ResponseBody
ModelAndViewMethodReturnValueHandler ModelAndView
ViewNameMethodReturnValueHandler 视图名
HttpEntityMethodProcessor ResponseEntity
CallableMethodReturnValueHandler 异步 Callable

源码流程:

java 复制代码
HandlerMethodReturnValueHandler handler = selectHandler(returnType);
handler.handleReturnValue(returnValue, returnType, mavContainer, request);

8. 拦截器执行顺序

HandlerExecutionChain:

复制代码
preHandle() → Controller → postHandle() → afterCompletion()

源码示例:

java 复制代码
if (!interceptor.preHandle()) return;
handler.invoke();
interceptor.postHandle();
interceptor.afterCompletion();

preHandle 顺序执行,afterCompletion 倒序执行,类似异常栈。


9. Controller 调用链全景图

Client Dispatcher HandlerMapping HandlerAdapter ArgumentResolvers Controller ReturnValueHandlers View HTTP 请求 getHandler() HandlerMethod getHandlerAdapter() resolve arguments() 参数集合 调用方法 返回数据 handleReturnValue() ModelAndView 渲染 HTML/JSON Client Dispatcher HandlerMapping HandlerAdapter ArgumentResolvers Controller ReturnValueHandlers View


10. Spring MVC 与 AOP 如何协作

AOP 代理发生在 BeanPostProcessor 阶段:

  • Controller 本身是代理对象
  • HandlerMapping 匹配的 HandlerMethod 是代理方法
  • AOP 的 MethodInterceptor 包裹 Controller 调用

请求链路:

复制代码
HTTP → DispatcherServlet → HandlerAdapter → AOP Proxy → Controller

11. 实战:自定义参数解析器

目标:自动解析 Header X-User-Id

1)定义注解

java 复制代码
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface UserId {}

2)自定义解析器

java 复制代码
public class UserIdArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(UserId.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter,
                                  ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest,
                                  WebDataBinderFactory binderFactory) {
        return webRequest.getHeader("X-User-Id");
    }
}

3)注册解析器

java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new UserIdArgumentResolver());
    }
}

4)Controller 使用

java 复制代码
@GetMapping("/me")
public String me(@UserId String uid) {
    return "uid=" + uid;
}

12. 超级总图:Spring MVC 全链路流程图

HTTP 请求进入 DispatcherServlet#doDispatch HandlerMapping 匹配 HandlerMethod HandlerAdapter 选择 解析器链 ArgumentResolvers Controller 方法调用 返回值处理器 ReturnValueHandlers 视图解析 ViewResolver 渲染 View HTTP Response 输出


13. 参考文档

结束语

👨‍💻 关于我

持续学习 | 追求真我

如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。
感谢订阅专栏 三连文章

掘金点击访问Qiuner CSDN点击访问Qiuner GitHub点击访问Qiuner Gitee点击访问Qiuner

专栏 简介
📊 一图读懂系列 图文并茂,轻松理解复杂概念
📝 一文读懂系列 深入浅出,全面解析技术要点
🌟持续更新 保持学习,不断进步
🎯 人生经验 经验分享,共同成长

你好,我是Qiuner. 为帮助别人少走弯路而写博客

如果本篇文章帮到了你 不妨点个 吧~ 我会很高兴的 😄 (^ ~ ^) 。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。

代码都在Github或Gitee上,如有需要可以去上面自行下载。记得给我点星星哦😍

如果你遇到了问题,自己没法解决,可以去我掘金评论区问。CSDN评论区和私信消息看不完 掘金消息少一点.

上一篇推荐 链接
Java程序员快又扎实的学习路线 点击该处自动跳转查看哦
一文读懂 AI 点击该处自动跳转查看哦
一文读懂 服务器 点击该处自动跳转查看哦
2024年创作回顾 点击该处自动跳转查看哦
一文读懂 ESLint配置 点击该处自动跳转查看哦
老鸟如何追求快捷操作电脑 点击该处自动跳转查看哦
未来会写什么文章? 预告链接
一文读懂 XX? 点击该处自动跳转查看哦
2025年终总结 点击该处自动跳转查看哦
一图读懂 XX? 点击该处自动跳转查看哦
相关推荐
Dwzun1 小时前
基于Java+SpringBoot+Vue的美甲店管理系统【附源码+文档+部署视频+讲解)
vue.js·spring boot·后端·毕业设计·计算机毕业设计
子一!!1 小时前
并查集(Union-Find)数据结构
java·数据结构·算法
哈库纳玛塔塔1 小时前
MongoDB 数据库 ORM/ODM 新工具
java·数据库·spring boot·mongodb·orm
小满、1 小时前
Redis:GUI 客户端(Redis Insight / Tiny RDM)、基础操作、Spring Boot 连接实现
java·redis·缓存·redis insight·tiny rdm
高林雨露1 小时前
App拉起小程序无法正常返回app 排查坑道
java·小程序
Victor3561 小时前
Netty(5)Netty的ByteBuf是什么?它与Java NIO的ByteBuffer有何不同?
后端
暗武逢天1 小时前
Java导出复杂Excel升级版(解决占位符遗留问题,通用工具类)
java·excel·easyexcel·模板导出·通用工具类
Victor3561 小时前
Netty(6)什么是Netty的Handler和Codec?
后端
cike_y2 小时前
Servlet原理&Mapping问题&ServletContext对象
java·安全·javaweb