SpringMVC 工作原理

SpringMVC 工作原理

SpringMVC 是 Spring 框架中用于构建 Web 应用的核心模块,其工作流程围绕 “前端控制器(DispatcherServlet)” 展开,通过组件间的协作完成请求处理与响应。理解其工作原理是掌握 SpringMVC 开发的关键,以下将通过 核心组件解析详细工作流程(含步骤拆解与流程图解) 两部分进行说明。

SpringMVC 核心组件

在了解流程前,需先明确参与请求处理的核心组件及其职责,各组件通过 Spring 容器管理,由 DispatcherServlet 调度。

组件名称核心职责
DispatcherServlet前端控制器(核心),统一接收所有请求,协调其他组件完成处理,避免组件耦合。
HandlerMapping处理器映射器,根据请求 URL 找到对应的 Handler(处理器,如 Controller 方法),返回 Handler 及拦截器链。
HandlerAdapter处理器适配器,适配不同类型的 Handler(如注解式 Controller、XML 配置的 Controller),调用 Handler 的业务方法。
Handler(处理器)业务逻辑处理器,即开发者编写的 Controller 类(或方法),负责处理具体业务逻辑。
ModelAndView处理器返回的结果对象,包含 Model(数据模型,如请求处理后的业务数据)View(视图名称,如 JSP 路径)
ViewResolver视图解析器,根据 ModelAndView 中的视图名称,解析为实际的 View 视图对象(如 JSP 文件、HTML 页面)。
View(视图)渲染视图,将 Model 中的数据填充到视图模板(如 JSP),生成最终的 HTML 响应给客户端。
Interceptor拦截器,可在请求处理的 预处理(前)、后处理(后)、完成处理(最终) 阶段插入自定义逻辑(如登录校验、日志记录)。

SpringMVC 完整工作流程(10 步拆解)

SpringMVC 的工作流程本质是 “DispatcherServlet 主导的组件协作流程”,从客户端发送请求到接收响应,共分为 10 个核心步骤,流程如下:

1. 流程步骤拆解
  1. 客户端发送 HTTP 请求
    用户通过浏览器、Postman 等工具发送请求(如 http://localhost:8080/springmvc/user/list),请求被 Web 服务器(如 Tomcat)接收。
  2. 请求被 DispatcherServlet 拦截
    Web 服务器根据 web.xml(或 SpringBoot 自动配置)中配置的 DispatcherServlet 映射规则(如 / 拦截所有请求,排除静态资源),将请求转发给 DispatcherServlet(前端控制器)。
  3. DispatcherServlet 调用 HandlerMapping
    DispatcherServlet 不直接处理请求,而是调用 HandlerMapping(处理器映射器),根据请求 URL、请求方法(GET/POST)等信息,查找对应的 Handler(如 Controller 中的 listUser() 方法),同时返回该 Handler 对应的 拦截器链(Interceptor Chain)
  4. DispatcherServlet 获取 HandlerAdapter
    DispatcherServlet 根据 Handler 的类型(如注解式 @Controller、实现 Controller 接口的类),调用对应的 HandlerAdapter(处理器适配器),确保后续能统一调用 Handler 的业务方法。
  5. 执行拦截器的预处理方法(preHandle)
    若存在拦截器,DispatcherServlet 会先执行拦截器链中所有拦截器的 preHandle() 方法。
    • 若任意一个拦截器的 preHandle() 返回 false,则请求终止,直接返回响应(可用于登录校验失败的场景);
    • 若全部返回 true,则继续执行后续流程。
  6. HandlerAdapter 调用 Handler 业务方法
    HandlerAdapter 调用 Handler(Controller 方法)的业务逻辑,处理请求(如查询数据库、处理参数),最终返回 ModelAndView 对象(包含业务数据 Model 和视图名称 ViewName,如 ModelAndView("user/list", "users", userList))。
  7. 执行拦截器的后处理方法(postHandle)
    Handler 执行完成后,DispatcherServlet 会倒序执行拦截器链中所有拦截器的 postHandle() 方法(此时 ModelAndView 已生成,可在此处修改视图或数据)。
  8. DispatcherServlet 调用 ViewResolver 解析视图
    DispatcherServlet 将 Handler 返回的 ModelAndView 传递给 ViewResolver(视图解析器),ViewResolver 根据视图名称(如 user/list)和配置的视图前缀(如 /WEB-INF/views/)、后缀(如 .jsp),解析为实际的 View 视图对象(如 /WEB-INF/views/user/list.jsp)。
  9. View 渲染视图并返回响应
    View 视图对象结合 Model 中的数据(如 users 列表),渲染生成 HTML 页面(将数据填充到 JSP 模板的标签中),并将渲染后的响应结果返回给 DispatcherServlet。
  10. 执行拦截器的完成处理方法(afterCompletion)
    响应返回前,DispatcherServlet 会倒序执行拦截器链中所有拦截器的 afterCompletion() 方法(无论请求是否成功,均会执行,可用于资源释放,如关闭流)。最终,DispatcherServlet 将响应结果返回给客户端(浏览器),流程结束。
2. 工作流程流程图(文字示意)
客户端(浏览器)  ↓ 1. 发送HTTP请求  
Web服务器(Tomcat)  ↓ 2. 转发给DispatcherServlet(根据映射规则)  
DispatcherServlet(前端控制器)  ↓ 3. 调用HandlerMapping  
HandlerMapping(处理器映射器)  ↓ 返回:Handler + 拦截器链  
DispatcherServlet  ↓ 4. 匹配HandlerAdapter  
HandlerAdapter(处理器适配器)  ↓ 5. 执行拦截器preHandle()(全部true则继续)  ↓ 6. 调用Handler(Controller方法)→ 返回ModelAndView  ↓ 7. 执行拦截器postHandle()(倒序)  
DispatcherServlet  ↓ 8. 调用ViewResolver解析视图  
ViewResolver(视图解析器)  ↓ 返回:实际View对象(如JSP)  ↓ 9. View渲染(Model数据填充到View)→ 生成HTML  ↓ 10. 执行拦截器afterCompletion()(倒序)  
DispatcherServlet  ↓ 返回响应  
客户端(浏览器)

关键总结

  1. DispatcherServlet 是 “中枢”:所有请求都经过它,负责协调 HandlerMapping、HandlerAdapter、ViewResolver 等组件,降低组件耦合。
  2. 组件职责单一:每个组件只做一件事(如 HandlerMapping 只负责找 Handler,ViewResolver 只负责解析视图),符合 “单一职责原则”。
  3. 拦截器作用于流程节点:通过 preHandlepostHandleafterCompletion 可在请求处理的关键节点插入自定义逻辑,增强灵活性。
  4. ModelAndView 是 “数据 + 视图” 载体:Handler 不直接渲染视图,而是返回 ModelAndView,由 ViewResolver 和 View 完成渲染,实现 “业务逻辑与视图分离”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/96247.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/96247.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HoRain云--Python机器学习神器:Sklearn全解析

🎬 HoRain云小助手:个人主页 🔥 个人专栏: 《Linux 系列教程》《c语言教程》 ⛺️生活的理想,就是为了理想的生活! ⛳️ 推荐 前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!…

疯狂星期四文案网第64天运营日记

网站运营第64天,点击观站: 疯狂星期四 crazy-thursday.com 全网最全的疯狂星期四文案网站 运营报告 今日访问量 今日搜索引擎收录情况

设计一个 AB 测试平台

1. 需求明确化 功能需求实验管理 创建、编辑、删除、复制实验设置实验参数(变体、权重、目标指标、时长等)实验状态管理(草稿、运行中、已结束)用户分流与分配 支持多种分流策略(随机分配、分层分配、定向分配&#xf…

HiCMAE 论文复现:基于 RAVDESS 数据集的音视频情感识别

HiCMAE 论文复现:基于 RAVDESS 数据集的音视频情感识别 1. 项目背景与论文概述 1.1 多模态情感识别背景 多模态情感识别是人工智能领域的重要研究方向,旨在通过结合多种感知模态(如音频、视频、文本等)来更准确地识别人类情感状态。与传统单模态方法相比,多模态方法能够…

HarmonyOS 数据处理性能优化:算法 + 异步 + 分布式实战

摘要 不管是写 App,还是做 IoT 设备开发,数据处理都是绕不开的主题。你可能要处理几百条传感器数据,也可能要应对几十万条用户行为日志。如果算法不够高效,应用就会卡顿甚至直接崩溃。尤其是在 HarmonyOS(鸿蒙系统&…

华为麒麟操作系统运维常见知识点

1.开放root账号密码登录。(1)修改/etc/ssh/sshd_config文件中,PermitRootLogin 属性值为yes。PermitRootLogin yes(2)使用passwd命令设置root密码。sudo su 切换到root账户下,使用passwd 设置密码。(3)重启sshd服务。systemctl restart sshd2.避免使用ch…

嵌入式面试|MCU+RTOS技术栈——面试八股文整理3:STM32

目录 1.单片机启动流程 2.看门狗 3.最小系统 4.ROM、RAM、Flash 5.EPROM、EEPROM 6.Bootloader与OTA 7.NAND FLASH 和NOR FLASH 相同点 区别 适用场景 8.CPU、MPU、MCU、SOC、SOPC 9.交叉编译 10.寄存器 寄存器的作用 寄存器与内存的区别 11.Cortex-M3寄存器组…

用 Wisdom SSH 轻松实现服务器自动化任务调度

用Wisdom SSH轻松实现服务器自动化任务调度 在服务器管理工作中,自动化任务调度至关重要,它能让系统在特定时间自动执行预设任务,极大提升运维效率。Wisdom SSH作为一款具备AI助手的强大工具,为自动化任务调度带来便捷解决方案。 …

远场学习_FDTD_dipole(1)

项目4.4 Reflection calculation using a dipole source在此页面中,我们采用了一种不同于标准平面波源方法的替代模拟设置,使用偶极子源来计算多层堆叠结构的反射。在此情况下,我们使用空气 - 玻璃界面。这种技术很有吸引力,因为它…

机器学习入门,用Lima在macOS免费搭建Docker环境,彻底解决镜像与收费难题!

国内用户必看】用Lima在macOS免费搭建Docker环境,彻底解决镜像与收费难题! 为了在不同操作系统有一致操作体验,我选择使用docker技术安装ollama,这样子还有一个好处,即使玩坏了,删除重建即可,所…

Java 生成签名证书

在Java中生成签名证书通常涉及到使用Java密钥和证书管理工具(Java Key and Certificate Management API,即Java Keytool)。这个过程通常包括创建密钥库(KeyStore),生成密钥对(Key Pair&#xff…

语法分析:编译器中的“语法警察”

在编程的世界里,每一种编程语言都有自己的语法规则。就像中文有标点符号和语序规则一样,编程语言也有自己严格的语法规则。语法分析器就像一个严格的"语法警察",它的职责是检查源代码是否符合语言规范,同时为后续的处理…

容器的定义及工作原理

定义 你可以把 容器 想象成一个 “打包好的软件快递箱”。 里面有什么? 这个箱子里不仅装着你的软件(比如一个网站程序),还把软件运行所需要的所有东西都打包进去了,比如它需要哪个版本的Python、需要哪些系统文件、配…

云服务扫盲笔记(2) —— SLS 接入与设置自动化

前篇我们学习了SLS的核心用途及概念,本篇以将一个linux服务器的json格式日志接入阿里云SLS为例,继续学习SLS接入中的关键设置及注意事项,以及如何将其实现简单自动化快速操作。 一、 SLS 日志接入流程 [1] 准备工作(确定日志路径…

LwIP入门实战 — 6 LwIP 网络数据包

目录 6.1 pbuf结构体 6.2 pbuf 的类型 6.2.1 PBUF_RAM 类型的pbuf 6.2.2 PBUF_POOL 类型的pbuf 6.2.3 PBUF_ROM 和 PBUF_REF 类型pbuf 6.3 pbuf 6.3.1 pbuf_alloc() 6.3.2 pbuf_free() 6.4 其它pbuf 操作函数 6.5 网卡中使用的 pbuf 6.5.1 low_level_output() 6.5.…

【已解决】Linux中程序脚本可以手动执行成功,但加在rc.local中不能开机自启

之前开发遇到的一个问题:在Linux中,明明程序脚本可以手动执行成功,但加到开机自启动里,却会失败,属实让人摸不着头脑。 问题排查: 有以下几种可能: 自启动脚本,执行权限不足或者脚本…

切块、清洗、烹饪:RAG知识库构建的三步曲

嘿,各位AI技术爱好者们,你是不是经常遇到这样的情况:辛辛苦苦训练的AI助手,面对专业问题时却"一问三不知"或者"胡言乱语"?明明你已经喂了它一堆PDF和Word文档,为啥它就是不会用&#x…

ubuntu 安装 docker 详细步骤

登录,ubuntu版本 22.04 wqbboy192.168.1.2s password: Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-153-generic x86_64)* Documentation: https://help.ubuntu.com* Management: https://landscape.canonical.com* Support: https://ubuntu.com/…

AndroidWorld+mobileRL

1、Android地址 https://github.com/google-research/android_world/tree/main?tabreadme-ov-file#installation 这里有排行榜,提交方式为手工提交到共享表格 https://docs.google.com/spreadsheets/d/1cchzP9dlTZ3WXQTfYNhh3avxoLipqHN75v1Tb86uhHo/edit?gid0#g…

《练手:ipv4地址计算和Telnet 远程设备管理配置实验文档》

实验一:IPv4 地址网段判断原理及实例 判断两个 IPv4 地址是否处于同一网段,核心依据是:将两个 IP 地址分别与子网掩码进行AND 运算后,得到的网络地址是否相同。若相同,则属于同一网段;反之则不属于。 实验拓…