Spring MVC 深度解析:原理、源码剖析与实战
Spring MVC 深度解析:原理、源码剖析与实战
在 Spring 体系中,Spring MVC 作为 Web 层的核心框架,承担着请求处理、参数解析、视图渲染等关键任务。今天,我们将深入剖析 Spring MVC 的执行流程,结合 源码分析,并通过 代码实战 掌握其核心机制。
📌 1. 什么是 Spring MVC?
Spring MVC(Model-View-Controller)是一种基于 Servlet 的 Web 框架,遵循 MVC 设计模式,主要负责:
- 请求分发(DispatcherServlet)
- 控制器映射(HandlerMapping)
- 参数解析(HandlerAdapter)
- 视图渲染(ViewResolver)
📌 2. Spring MVC 执行流程解析
Spring MVC 处理请求的完整流程如下:
1️⃣ 客户端发送 HTTP 请求(如 GET /user/list)
2️⃣ DispatcherServlet 拦截请求,作为 MVC 的中央调度器
3️⃣ HandlerMapping 查找对应的 Controller(基于 URL 映射)
4️⃣ HandlerAdapter 适配执行 Controller 业务逻辑
5️⃣ Controller 处理请求并返回 ModelAndView
6️⃣ ViewResolver 解析视图并渲染数据
7️⃣ 返回 HTML 响应给客户端
📌 Spring MVC 内部架构图:
[Client] → [DispatcherServlet] → [HandlerMapping] → [Controller] →
[ModelAndView] → [ViewResolver] → [Response]
📌 3. 源码解析:DispatcherServlet 如何工作?
🔥 DispatcherServlet 核心源码
Spring MVC 通过 DispatcherServlet 作为 前端控制器,其核心方法 doDispatch() 负责处理请求:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {// 1️⃣ 解析请求对应的 Handler(Controller)HandlerExecutionChain handler = getHandler(request);// 2️⃣ 选择合适的 HandlerAdapter 执行 Controller 方法HandlerAdapter ha = getHandlerAdapter(handler.getHandler());// 3️⃣ 调用 Controller 方法,获取 ModelAndViewModelAndView mv = ha.handle(request, response, handler.getHandler());// 4️⃣ 解析视图,并返回响应结果processDispatchResult(request, response, handler, mv);
}
✅ 核心流程
getHandler():查找HandlerMapping获取对应的 ControllergetHandlerAdapter():找到适配 Controller 方法的HandlerAdapterhandle():执行 Controller 逻辑,返回ModelAndViewprocessDispatchResult():调用ViewResolver解析视图,渲染响应
📌 4. 代码实战:手写 Spring MVC Controller
我们基于 Spring Boot 构建一个简单的 Spring MVC 应用,并实现 @RequestMapping 的 Controller。
📝 代码示例:Spring Boot MVC 控制器
import org.springframework.web.bind.annotation.*;import java.util.*;@RestController
@RequestMapping("/user")
public class UserController {// 模拟数据库存储用户private static List<String> users = new ArrayList<>(Arrays.asList("Alice", "Bob", "Charlie"));// 查询用户列表@GetMapping("/list")public List<String> listUsers() {return users;}// 添加用户@PostMapping("/add")public String addUser(@RequestParam String name) {users.add(name);return "用户 " + name + " 添加成功!";}
}
🛠 启动 Spring Boot
在 SpringBootApplication 类中运行:
@SpringBootApplication
public class SpringMvcApp {public static void main(String[] args) {SpringApplication.run(SpringMvcApp.class, args);}
}
✅ 测试 API
# 查询用户列表
curl http://localhost:8080/user/list# 添加新用户
curl -X POST "http://localhost:8080/user/add?name=David"
📌 5. 深入分析 @RequestMapping 的执行流程
@RequestMapping 是 Spring MVC 用于 URL 映射 的核心注解,它的执行流程如下:
1️⃣ Spring MVC 启动时,扫描 @RequestMapping 标注的方法
2️⃣ HandlerMapping 解析 URL,并映射到 Controller 方法
3️⃣ HandlerAdapter 调用 Controller 方法,解析 @RequestParam 参数
4️⃣ 返回结果封装为 ResponseBody,通过 HttpMessageConverter 处理
📌 源码解析:Spring MVC 如何解析 @RequestMapping?
@RequestMapping("/user")
public class UserController {@GetMapping("/list")public List<String> listUsers() { return users; }
}
➡️ 核心逻辑:
Spring MVC 在启动时,会通过 RequestMappingHandlerMapping 解析 @RequestMapping 并存入映射表:
protected void detectHandlerMethods(Object handler) {for (Method method : handler.getClass().getDeclaredMethods()) {if (method.isAnnotationPresent(RequestMapping.class)) {registerHandlerMethod(handler, method);}}
}
📌 6. Spring MVC 过滤器与拦截器
Spring MVC 提供 Filter 和 Interceptor 机制,可用于 用户认证、日志记录、跨域请求 等场景。
| 类型 | 作用 | 实现方式 |
|---|---|---|
| Filter | 过滤 HTTP 请求 | javax.servlet.Filter |
| Interceptor | 拦截 Controller | HandlerInterceptor |
📝 代码示例:拦截器实现日志记录
@Component
public class LogInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {System.out.println("请求路径:" + request.getRequestURI());return true;}
}
✅ 注册拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LogInterceptor());}
}
🔹 作用:每次请求前打印日志,方便调试。
📌 7. 总结
| 功能 | Spring 机制 | 源码解析 | 代码实战 |
|---|---|---|---|
| 请求分发 | DispatcherServlet | doDispatch() 方法 | @RequestMapping |
| Controller 处理 | HandlerMapping | getHandler() | @RestController |
| 参数解析 | HandlerAdapter | handle() 方法 | @RequestParam |
| 视图渲染 | ViewResolver | processDispatchResult() | return ModelAndView |
✅ 今日收获:
- 掌握 Spring MVC 执行流程
- 深入理解 DispatcherServlet 处理逻辑
- 解析 @RequestMapping 的工作机制
- 实战 Spring Boot MVC 开发
- 实现 日志拦截器
🚀 明日预告:Spring 事务管理(事务传播、@Transactional 源码分析)
🔗 学习资料:
📖 Spring 官方文档 - MVC
💬 Spring MVC 你有什么疑问?欢迎留言交流! 🚀
相关文章:
Spring MVC 深度解析:原理、源码剖析与实战
Spring MVC 深度解析:原理、源码剖析与实战 在 Spring 体系中,Spring MVC 作为 Web 层的核心框架,承担着请求处理、参数解析、视图渲染等关键任务。今天,我们将深入剖析 Spring MVC 的执行流程,结合 源码分析…...
347 前k个高频元素
步骤1:统计元素频率 使用哈希表(unordered_map)统计每个元素的出现次数,时间复杂度为 O(n)。 步骤2:构建最小堆维护Top K 优先队列(最小堆):用priority_queue维护当前频率最高的k…...
BUUCTF-web刷题篇
1.EASYSQL破解密码 万能公式: 1 and 11 1 and 11 1 or 11 1 or 11 解释:payload SELECT * FROM tables WHERE username1 or 11 and password1 or 11 优先级排序:and 优先级高于 or,所以要计算 and 然后再计算 or username1…...
LeetCode 第31~33题
目录 LeetCode 第31题:下一个排列 LeetCode 第32题:最长有效括号 LeetCode 第33题:搜索旋转排序数组 LeetCode 第31题:下一个排列 题目描述 整数数组的一个排列就是将所有成员以序列或线性顺序排列。例如arr[1,2,3],以…...
【NLP 44、实践 ⑪ 用Bert模型结构实现自回归语言模型的训练】
目录 数据文件 一、模型定义 1.模型初始化 代码运行流程 2.前向传播,计算损失 ⭐ 代码运行流程 二、加载语料 代码运行流程 三、 随机生成样本 代码运行流程 四、建立模型 五、采样策略选择 代码运行流程 六、模型效果测试 代码运行流程 七、模型训练 代码运行流程 …...
Go 语言规范学习(1)
文章目录 IntroductionNotation示例(Go 语言的 if 语句): Source code representationCharacters例子:变量名可以是中文 Letters and digits Lexical elementsCommentsTokensSemicolons例子:查看程序所有的token Ident…...
ShapeCrawler:.NET开发者的PPTX操控魔法
引言 在当今的软件开发领域,随着数据可视化和信息展示需求的不断增长,处理 PPTX 文件的场景日益频繁。无论是自动化生成报告、批量制作演示文稿,还是对现有 PPT 进行内容更新与格式调整,开发者都需要高效的工具来完成这些任务。传…...
微信小程序如何接入直播功能
一、小程序直播开通背景 1.政府资质要求 政府的要求,小程序开通直播需要注册主体具备互联网直播的资质,普通企业需要《信息网络传播视听节目许可证》,表演性质的直播需要《网络文化经营许可证》,政府主体需要《社会信用代码》及…...
ArrayList<E>案例//定义一个方法,将价格低于3000的手机信息返回
import java.util.ArrayList;public class ArrayListphone {public static void main(String[] args){//定义一个方法,将价格低于3000的手机信息返回Phone p1new Phone("小米",1000);Phone p2new Phone("苹果",8000);Phone p3new Phone("锤…...
基于Spring Boot的停车场管理系统的设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
慧通测控汽车智能座舱测试技术
一、引言 随着科技的飞速发展,汽车正从单纯的交通工具向智能化移动空间转变。智能座舱作为这一转变的核心体现,融合了多种先进技术,为用户带来前所未有的驾驶体验。从简单的信息娱乐系统到高度集成的人机交互、智能驾驶辅助以及车辆状态监测…...
Qt进程间通信:QSharedMemory 使用详解
1. 什么是 QSharedMemory? QSharedMemory 是 Qt 中用于进程间共享内存的类。它允许多个进程共享一块内存区域,从而避免数据传输时的 IO 操作,提高通信速度。通过共享内存,多个进程可以直接读写这块内存,而无需经过文件…...
kettle插件-rabbitmq插件
场景:kettle本身可以直接链接rabbitmq,但是需要配置rabbitmq开启mqtt协议,本次讲解下自定义开发组件RabbitMQ consumer,无需开启mqtt协议即可使用。 1、docker 安装rabbitmq 1)下载镜像 docker pull rabbitmq 2&…...
为Windows10的WSL Ubuntu启动sshd服务并使用Trae远程连接
Windows10的WSL Ubuntu,使用起来非常方便,但是美中不足的是,无法从Windows主机ssh到Ubuntu 。 解决的方法是在Ubuntu安装sshd服务 Ubuntu安装sshd服务 执行命令 sudo apt install openssh-server 安装好后,先本地测试&#x…...
【C#.NET】VS2022创建Web API项目
C# Web API 是一种基于 .NET 平台(包括但不限于.NET Framework 和 .NET Core)构建 HTTP 服务的框架,用于创建 RESTful Web 服务。REST(Representational State Transfer)是一种软件架构风格,它利用HTTP协议…...
体育直播系统趣猜功能开发技术实现方案
功能概述 趣猜功能是“东莞梦幻网络科技”体育直播系统源码中的互动功能,主播可以发起竞猜题目,观众使用虚拟货币进行投注,增加直播间的互动性和趣味性。所有货币均为虚拟货币,通过系统活动获取,不可充值提现。 数据…...
33.[前端开发-JavaScript基础]Day10-常见事件-鼠标事件-键盘事件-定时器-案例
1 window定时器 window定时器方法 setTimeout的使用 setInterval的使用 2 轮播消息提示 案例实战一 – 轮播消息提示 3 关闭隐藏消息 案例实战二 – 关闭隐藏消息 4 侧边栏展示 案例实战三 – 侧边栏展示 5 tab切换实现 案例实战四 – 登录框(作业)…...
C# 多标签浏览器 谷歌内核Csharp
采用框架 :FBrowserCEF3lib 视频演示:点我直达 成品下载: https://wwms.lanzouo.com/iYOd42rl8vje...
如何同步fork的更新
当你fork了一个代码仓库后,要将其与原始源码保持同步,可以按照以下步骤进行操作: 1. 添加原始仓库作为远程源 在本地命令行中,进入到你fork后的代码仓库目录,然后使用以下命令添加原始仓库(通常称为upstr…...
如何从0设计开发一款JS-SDK
一、前言 前端SDK是什么?前端SDK是为了帮助前端实现特定需求,而向开发者暴露的一些JS-API的集合,规范的SDK包括若干API实现、说明文档等 前端SDK其实很常见了,比如: UI组件库:通过封装一系列组件ÿ…...
linux实现rsync+sersync实时数据备份
1.概述 rsync(Remote Sync) 是一个Unix/linux系统下的文件同步和传输工具 2.端口和运行模式 tcp/873 采用C/S模式(客户端/服务器模式) 3.特点 可以镜像保存整个目录和文件第一次全量备份(备份全部的文件),之后是增量备份(只备份变化的文件) 4. 数…...
【计算机网络】计算机网络协议、接口与服务全面解析——结合生活化案例与图文详解
协议、接口与服务 导读一、协议1.1 定义1.2 组成 二、接口三、服务3.1 定义3.2 服务与协议的区别3.3 分类3.3.1 面向连接服务于无连接服务3.3.2 可靠服务和不可靠服务3.3.3 有应答服务和无应答服务 结语 导读 大家好,很高兴又和大家见面啦!!…...
51c自动驾驶~合集26
我自己的原文哦~ https://blog.51cto.com/whaosoft/11968755 #大模型/Sora/世界模型之间是什么关系 1 什么是大模型 人工智能大模型(Artificial Intelligence Large Model,简称AI大模型)是指具有庞大的参数规模和复杂程度的机器学习模…...
【汽车传感系统架构:借助传感获取安全】
为了将车辆自动化提升到一个新的水平,设计人员研究了 LiDAR 等传感器选项的权衡,并着眼于传感系统架构。 本文引用地址:https://www.eepw.com.cn/article/202503/468584.htm 每年,约有 120 万人死于道路交通事故,还有…...
【NUUO 摄像头】(弱口令登录漏洞)
漏洞简介:NUUO 是NUUO公司的一款小型网络硬盘录像机设备。 NUUO NVRMini2 3.0.8及之前版本中存在后门调试文件。远程攻击者可通过向后门文件handle_site_config.php发送特定的请求利用该漏洞执行任意命令。 1.Fofa搜索语句: 在Fofa网站,搜索&…...
论文阅读笔记:Denoising Diffusion Probabilistic Models (3)
论文阅读笔记:Denoising Diffusion Probabilistic Models (1) 论文阅读笔记:Denoising Diffusion Probabilistic Models (2) 论文阅读笔记:Denoising Diffusion Probabilistic Models (3) 4、损失函数逐项分析 可以看出 L L L总共分为了3项…...
【设计模式】抽象工厂模式(含与工厂方法模式的对比)
本期我们来学习一下设计模式之抽象工厂模式,在软件开发中,工厂模式 和 抽象工厂模式 都用于创建对象,但它们的应用场景和实现方式有所不同。本文将基于 C 代码,分析抽象工厂模式的实现,并对比其与工厂方法模式的区别。…...
消息队列保证最终一致性的优势
消息队列保证最终一致性的优势 使用消息队列(如Kafka、RabbitMQ等)来实现MySQL和Redis之间的最终一致性,具有以下几个显著优势: 1. 解耦系统组件 降低系统耦合度:生产者(MySQL更新)和消费者&…...
IDEA转战Trae AI IED配置
Trae Ai 的前身是vscode IDEA转战Trae AI IED配置 1.安装java相关的插件 2、安装spring相关的插件 3.配置maven环境 打开 Trae AI IDE -> 首选项 -> 设置 -> Editor 设置 ⚠️配置方式有两种 setting.json文件中直接编辑(推荐)界面设置 方案…...
再学:区块链基础与合约初探 EVM与GAS机制
目录 1.区块链是什么 2.remix 3.账户 4.以太坊三种交易 5.EVM 6.以太坊客户端节点 7.Gas费用 8.区块链浏览器 1.区块链是什么 只需要检验根节点 Merkel根是否有更改,就不用检查每个交易是否有更改。方便很多。 2.remix 3.账户 如果交易失败的话&…...
