当前位置: 首页 > news >正文

Spring MVC 处理请求的流程

Spring MVC 处理请求的流程

      • 流程步骤详解
        • 第1步:发起请求 (HTTP Request)
        • 第2步:映射处理器 (Handler Mapping)
        • 第3步:获取适配器 (Handler Adapter)
        • 第4步:执行拦截器前置处理 (Interceptors - preHandle)
        • 第5步:真正调用处理器 (Handler Execution)
        • 第6步:执行拦截器后置处理 (Interceptors - postHandle)
        • 第7步:处理分发结果 (Process Dispatch Result)
        • 第8步:执行拦截器完成处理 (Interceptors - afterCompletion)
        • 第9步:返回响应 (HTTP Response)
      • 核心组件总结

Spring MVC 处理请求的流程是其最核心的机制,理解它对于掌握整个框架至关重要。这个过程围绕一个核心——前端控制器模式(Front Controller Pattern),即 DispatcherServlet。

整个流程清晰且模块化,下图展示了从请求发起到响应返回的完整生命周期,以及其中涉及的核心组件交互:

ClientDispatcherServlet(前端控制器)HandlerMappingHandlerAdapterController (@Controller)ViewResolverView (JSP/Thymeleaf...)HTTP Request1. 接收请求查询Handler2. 映射查找根据URL找到目标Controller和方法返回HandlerExecutionChain(包含Handler和Interceptors)3. 适配调用获取HandlerAdapter返回Adapter按顺序执行preHandle()loop[4. 执行拦截器 (preHandle)]5. 处理请求(参数解析、方法调用、返回值处理)调用Controller方法返回方法执行结果(ModelAndView/String等)逆序执行postHandle()loop[6. 执行拦截器 (postHandle)]7. 处理视图/响应通过HttpMessageConverter直接写回响应解析视图名返回View对象调用render()渲染视图返回渲染后的HTMLalt[返回@ResponseBody][返回视图名]最终触发afterCompletion()loop[8. 执行拦截器 (afterCompletion)]9. 返回响应HTTP ResponseClientDispatcherServlet(前端控制器)HandlerMappingHandlerAdapterController (@Controller)ViewResolverView (JSP/Thymeleaf...)

流程步骤详解

现在,我们结合上图,对每一个步骤进行详细解读:

第1步:发起请求 (HTTP Request)

请求离开浏览器,到达 DispatcherServlet。根据 web.xml 或 Servlet 3.0+ 的配置,所有匹配特定模式(如 /)的请求都会由它处理。

第2步:映射处理器 (Handler Mapping)

DispatcherServlet 咨询一个或多个 HandlerMapping Bean:“这个请求应该由哪个‘处理器’(Handler)来处理?”。HandlerMapping 根据请求的 URL 进行查找。

  • 常见实现
    • RequestMappingHandlerMapping:用于映射 @RequestMapping 注解的方法(最常用)。
    • BeanNameUrlHandlerMapping:根据 Bean 的名字进行映射。
  • 返回结果:不仅返回找到的目标处理器方法,还会返回一个 HandlerExecutionChain 对象,该对象包含了找到的 Handler 以及所有适用于该请求的 HandlerInterceptor(拦截器)。
第3步:获取适配器 (Handler Adapter)

DispatcherServlet 拿着找到的 Handler,问一堆 HandlerAdapter:“你们谁支持(support)这个 Handler 的类型?”

  • 为什么需要它?:Handler 的类型五花八门(如 @ControllerHttpRequestHandlerServlet)。DispatcherServlet 需要一個统一的接口来调用它们。HandlerAdapter适配器模式的典型应用,它屏蔽了不同处理器的调用细节。
  • 常见实现RequestMappingHandlerAdapter(用于适配 @RequestMapping 注解的方法)。
第4步:执行拦截器前置处理 (Interceptors - preHandle)

在真正调用业务逻辑之前,DispatcherServlet 会调用 HandlerExecutionChain 中所有拦截器的 preHandle() 方法。

  • 应用:进行权限检查、日志记录、 locale 解析等。
第5步:真正调用处理器 (Handler Execution)

现在,DispatcherServlet 让获取到的 HandlerAdapter 去真正地执行 Handler。
这个执行过程非常复杂,包括:

  1. 参数解析:根据方法签名,使用各种 HandlerMethodArgumentResolver 来解析方法的参数(如 @RequestParam, @RequestBody, @PathVariable)。
  2. 调用方法:通过反射调用控制器方法。
  3. 返回值处理:使用方法返回值,使用各种 HandlerMethodReturnValueHandler 处理返回值(如 @ResponseBody, ModelAndView)。
第6步:执行拦截器后置处理 (Interceptors - postHandle)

控制器方法执行完毕后,DispatcherServlet逆序调用所有拦截器的 postHandle() 方法。

  • 应用:有机会修改即将发送到视图的 ModelAndView 对象。
第7步:处理分发结果 (Process Dispatch Result)

这是视图渲染和响应的核心环节。DispatcherServlet 根据控制器方法的返回结果,进行不同的处理:

  • 情况A:方法有 @ResponseBody 或返回 ResponseEntity
    • 流程RequestResponseBodyMethodProcessor 会使用配置的 HttpMessageConverter(如 MappingJackson2HttpMessageConverter)将返回值(如一个 Java 对象)直接序列化(如转为 JSON),并写入 HttpServletResponse 的输出流。此过程不涉及视图解析。
  • 情况B:方法返回视图名(如 String)或 ModelAndView
    • 视图解析DispatcherServlet 调用 ViewResolver 来根据逻辑视图名(如 "success")解析为一个具体的 View 对象(如 InternalResourceView 对应 JSP,ThymeleafView 对应 Thymeleaf)。
    • 视图渲染DispatcherServlet 将模型数据传递给 View 对象,并调用其 render() 方法。该方法会生成最终的 HTML 内容(如合并 JSP 模板和模型数据),并将其写入 HttpServletResponse 的输出流。
第8步:执行拦截器完成处理 (Interceptors - afterCompletion)

无论请求处理成功还是出现异常,DispatcherServlet 都会最终触发所有拦截器的 afterCompletion() 方法。

  • 应用:进行资源清理、记录请求完成时间等。
第9步:返回响应 (HTTP Response)

最终,完整的响应通过 Servlet 容器(如 Tomcat)返回给客户端。


核心组件总结

组件职责类比
DispatcherServlet前端控制器,协调所有组件,是整个流程的总指挥。餐厅的前台经理
HandlerMapping请求映射,根据 URL 找到对应的处理器。餐厅的引座员
HandlerAdapter处理器适配,用统一的接口调用各种不同类型的处理器。餐厅的服务员,连接经理和后厨
Handler处理器(通常是我们写的 @Controller)。餐厅的厨师
ViewResolver视图解析器,将逻辑视图名解析为具体视图对象。餐厅的出菜员
View视图,负责将模型数据渲染成最终的响应内容(HTML/JSON等)。最终呈现的菜肴
HandlerInterceptor拦截器,在请求处理的不同阶段进行横切处理。餐厅的质检员

这个流程充分体现了 Spring MVC 的高度可配置性和可扩展性。其中的每一个步骤几乎都可以通过配置自定义组件或实现特定接口来进行干预和扩展。


文章转载自:

http://0EPTgAEq.sxjmz.cn
http://lZ4g64wF.sxjmz.cn
http://FlahFgWa.sxjmz.cn
http://yDQzusM5.sxjmz.cn
http://6jE4HJEX.sxjmz.cn
http://445m34Gw.sxjmz.cn
http://DcZWdYEB.sxjmz.cn
http://0XyTT7xH.sxjmz.cn
http://jHN1cSYt.sxjmz.cn
http://Q1VOkNEh.sxjmz.cn
http://rp75UmsQ.sxjmz.cn
http://cXIeNczo.sxjmz.cn
http://eXmIXaVA.sxjmz.cn
http://8fs3ZFpM.sxjmz.cn
http://0zefKYAZ.sxjmz.cn
http://geuMfiK7.sxjmz.cn
http://UqcrKPwS.sxjmz.cn
http://YD8LtaGS.sxjmz.cn
http://y5pz2oK3.sxjmz.cn
http://c8mkviyF.sxjmz.cn
http://YLC5fnfP.sxjmz.cn
http://iAQgjdRH.sxjmz.cn
http://1CSfTFdX.sxjmz.cn
http://9OkoPqYR.sxjmz.cn
http://2j0fcDHc.sxjmz.cn
http://MNMP6L36.sxjmz.cn
http://9BOPWReA.sxjmz.cn
http://7mh09Dql.sxjmz.cn
http://vPCZNqc5.sxjmz.cn
http://HCYmHYi5.sxjmz.cn
http://www.dtcms.com/a/369854.html

相关文章:

  • 从机器学习的角度实现 excel 中趋势线:揭秘梯度下降过程
  • Docker部署搜索引擎SearXNG
  • Hadoop(八)
  • 【Python自动化】 21.2 Pandas 读取 Excel 时的 dtype 参数完全指南
  • 【面板数据】各省制造业出口技术复杂度数据集(2010-2023年)
  • 使用 YAML 自动化 Azure DevOps 管道
  • 【数据库相关】TxSQL新增数据库节点步骤
  • 理想汽车智驾方案介绍 4 World model + 强化学习重建自动驾驶交互环境
  • 大语言模型预训练数据采集与清洗技术实践:从语料到知识库的全流程优化
  • 腾讯混元翻译模型Hunyuan-MT-7B开源,先前拿了30个冠军
  • MiniDrive:面向自动驾驶的更高效的视觉语言模型
  • 2025年渗透测试面试题总结-54(题目+回答)
  • 《Kubernetes 构建 MySQL MGR 集群实战教程》
  • 创建阿里云ECS实例操作(免费试用版)
  • 【数学建模】质量消光系数在烟幕遮蔽效能建模中的核心作用
  • 小孔成像原理
  • 操作系统基本概念.1
  • Jupyter Notebook与cpolar:构建跨地域数据科学协作平台
  • 山西移动九联UNT413HS-海思MV320-2+8G-原机全量备份包
  • AI热点周报(8.31~9.6): Qwen3‑Max‑Preview上线、GLM-4.5提供一键迁移、Gemini for Home,AI风向何在?
  • 【C++】C++11的可变参数模板、emplace接口、类的新功能
  • [特殊字符] 从零到一:打造你的VSCode圈复杂度分析插件
  • JVM如何排查OOM
  • Miniconda安装与VSCode搭建远程Python、Jupyter开发环境
  • 智能客户服务支持智能体
  • Gutenberg块编辑器:WordPress 2025高效内容开发指南
  • JUC、JVM八股补充
  • windows找不到gpedit.msc(本地组策略编辑器)
  • 【洛谷】队列相关经典算法题详解:模板队列、机器翻译、海港
  • 激光频率梳 3D 轮廓测量 - 油路板的凹槽深度和平面度测量