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

spring mvc源码学习笔记之五

  • pom.xml 内容如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.qsm</groupId><artifactId>learn</artifactId><version>1.0.0</version></parent><groupId>com.qs</groupId><artifactId>demo-43</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.28</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency></dependencies></project>
  • web.xml 内容如下
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"metadata-complete="true"><!-- 第一个 servlet | 单独一个容器 --><servlet><servlet-name>app1</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/app1-servlet.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>app1</servlet-name><url-pattern>/app1/*</url-pattern></servlet-mapping><!-- 第二个 servlet | 单独一个容器 --><servlet><servlet-name>app2</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/app2-servlet.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>app2</servlet-name><url-pattern>/app2/*</url-pattern></servlet-mapping></web-app>
  • src/main/webapp/WEB-INF/app1-servlet.xml 内容如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="peopleController" class="com.qs.demo.s1.PeopleV1Controller"/>
</beans>
  • src/main/webapp/WEB-INF/app2-servlet.xml 内容如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="peopleController" class="com.qs.demo.s2.PeopleV2Controller"/>
</beans>
  • com.qs.demo.s1.PeopleV1Controller 内容如下
package com.qs.demo.s1;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author qs* @date 2023/07/05*/
@RestController
public class PeopleV1Controller {// RequestMappingHandlerAdapter 处理@RequestMapping("/p1/01")public String test01() {return "demo43 V1 01";}@RequestMapping("/p1/02")public String test02() {return "demo43 V1 02";}
}
  • com.qs.demo.s2.PeopleV2Controller 内容如下
package com.qs.demo.s2;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;/*** @author qs* @date 2023/07/05*/
@Controller
public class PeopleV2Controller {// RequestMappingHandlerAdapter 处理@GetMapping("/p2/01")@ResponseBodypublic String test01() {return "demo43 V2 01";}@GetMapping("/p2/02")@ResponseBodypublic String test02() {return "demo43 V2 02";}
}

以上就是全部代码

写这个例子主要是想说一个知识点。也就是说我们平时用 spring mvc 的时候,都会配置一个 DispatcherServlet 来处理所有请求。
其实是可以配置多个的。这不难理解:回忆一下刚学 servlet 的时候,我们不就是写多个 servlet 来处理不同的请求么。
DispatcherServlet 也是个 servlet 。自然遵循这个逻辑。

知道可以这样写就行。这种写法是不建议的。spring mvc 本来就是设计的用一个 DispatcherServlet (前端控制器)来接受所有请求。

多说一嘴。从这个例子中我们也能解答一个面试题:spring 中能存在 id 相同的 bean 吗?答案是:能。
原理很简单。只要 id 相同的 bean 在不同的应用上下文中就行了。
在上面的例子中,我们定义了 2 个名为 peopleController 的 bean。之所以不冲突,是因为他们分别属于 2 个 servlet 。而每个 servlet 又维护了自己的 web 应用上下文。

怎么验证 2 个 DispatcherServlet 用的是不同的web应用上下文呢?
非常简单。只需要让 2 个控制器都实现 ApplicationContextAware 接口,在控制器中打印或者打断点看就行了。如下

package com.qs.demo.s1;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author qs* @date 2023/07/05*/
@RestController
public class PeopleV1Controller implements ApplicationContextAware {// RequestMappingHandlerAdapter 处理private ApplicationContext applicationContext;@RequestMapping("/p1/01")public String test01() {System.out.println(applicationContext);System.out.println(applicationContext.getId());return "demo43 V1 01";}@RequestMapping("/p1/02")public String test02() {return "demo43 V1 02";}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}
}
package com.qs.demo.s2;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;/*** @author qs* @date 2023/07/05*/
@Controller
public class PeopleV2Controller implements ApplicationContextAware {// RequestMappingHandlerAdapter 处理private ApplicationContext applicationContext;@GetMapping("/p2/01")@ResponseBodypublic String test01() {System.out.println(applicationContext);System.out.println(applicationContext.getId());return "demo43 V2 01";}@GetMapping("/p2/02")@ResponseBodypublic String test02() {return "demo43 V2 02";}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}
}

分别调用 /mvc_43/app1/p1/01 和 /mvc_43/app2/p2/01 打印如下

WebApplicationContext for namespace 'app1-servlet', started on Sat Jan 04 15:09:26 CST 2025
org.springframework.web.context.WebApplicationContext:/mvc_43/app1
WebApplicationContext for namespace 'app2-servlet', started on Sat Jan 04 15:09:25 CST 2025
org.springframework.web.context.WebApplicationContext:/mvc_43/app2

相关文章:

spring mvc源码学习笔记之五

pom.xml 内容如下 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…...

3272 小蓝的漆房

将devc设置支持编译就能用新的遍历方式 for(auto &x : s)//遍历容器s&#xff0c;变量为x /* 多循环的嵌套&#xff1a; 计数是否需要重置为0; 是否因为ans定义成全局变量导致ans在比较多时候会出现错误*/ /* 1.对于一个标准色&#xff0c;对目标数组遍历&#xff0c; 如…...

MySQL使用触发器进行备份

触发器脚本备份 实现方案&#xff1a; 1.配置mysql调用外部脚本的插件mysqludf 链接&#xff1a;https://pan.baidu.com/s/1MCrf1u_SRWwcZoxM9JDNiw 提取码&#xff1a;kgt0 解压 2.解压后放进&#xff1a; mysql安装路径/lib/plugin/ 3.在mysql执行命令创建自定义函数&…...

数据结构与算法-顺序表

数据结构 顺序表 基本概念 顺序表&#xff1a;顺序存储的线性表链式表&#xff1a;链式存储的线性表&#xff0c;简称链表 顺序存储就是将数据存储到一片连续的内存中&#xff0c;在C语言环境下&#xff0c;可以是具名的栈数组&#xff0c;也可以是匿名的堆数组。 存储方式…...

OpenAI CEO 奥特曼发长文《反思》

OpenAI CEO 奥特曼发长文《反思》 --- 引言&#xff1a;从 ChatGPT 到 AGI 的探索 ChatGPT 诞生仅一个多月&#xff0c;如今我们已经过渡到可以进行复杂推理的下一代模型。新年让人们陷入反思&#xff0c;我想分享一些个人想法&#xff0c;谈谈它迄今为止的发展&#xff0c;…...

Shell编程详解

文章目录 一、Linux系统结构二、Shell介绍1、Shell简介2、Shell种类3、Shell查询和切换 三、Shell基础语法1、注释2、本地变量3、环境变量3.1、查看环境变量3.2、临时设置环境变量3.3、永久设置环境变量 4、特殊变量5、控制语句5.1、shell中的中括号5.2、if语句5.3、for循环5.4…...

跨站脚本攻击(XSS)详解

跨站脚本攻击&#xff08;XSS&#xff09;详解 跨站脚本攻击&#xff08;XSS&#xff0c;Cross-Site Scripting&#xff09;是一种通过在网页中注入恶意脚本&#xff0c;攻击用户浏览器的漏洞。攻击者可以利用XSS窃取用户敏感信息、劫持会话、或在受害者浏览器中执行恶意操作。…...

03-QT中的QMainWindow+对话框QDialog

文章目录 1.QMainWindow1.1菜单栏1.2 工具栏1.3 状态栏1.4 铆接部件1.5 核心部件&#xff08;中心部件&#xff09;1.6 资源文件 2.对话框2.1 基本概念2.2 标准对话框2.3 自定义消息框2.4 消息对话框2.5 标准文件对话框 1.QMainWindow QMainWindow是一个为用户提供主窗口程序的…...

c# 中Parallel.ForEach 对其中一个变量进行赋值 引发报错

在 C# 中使用 Parallel.ForEach 方法时&#xff0c;如果你尝试在并行循环中对共享变量进行赋值&#xff0c;很可能会遇到线程安全问题或竞争条件&#xff08;race conditions&#xff09;&#xff0c;这可能导致数据不一致、程序崩溃或其他不可预测的行为。 问题描述 假设你有…...

ElasticSearch备考 -- 整体脉络梳理

1、 search 、Update、reindex ElasticSearch 备考 -- 查询&高亮&排序 ElasticSearch 备考 -- 聚合查询 ElasticSearch 备考 -- 异步检索 2、search temple ElasticSearch备考 -- Search template 3、custom analyzer ElasticSearch 备考 -- 自定义分词 2、…...

vue Element Ui Upload 上传 点击一个按钮,选择多个文件后直接上传,使用防抖解决多次上传的问题。

问题&#xff1a; 在使用Element Ui Upload 上传文件时&#xff0c;选择多个文件上传时&#xff0c;on-change事件会一个一个返回上传的文件&#xff0c;导致前端不知道什么时候可以拿到全部上传的文件&#xff0c;再一起调后台接口。 解决方法&#xff1a; 上传文件后&…...

【HF设计模式】05-单例模式

声明&#xff1a;仅为个人学习总结&#xff0c;还请批判性查看&#xff0c;如有不同观点&#xff0c;欢迎交流。 摘要 《Head First设计模式》第5章笔记&#xff1a;结合示例应用和代码&#xff0c;介绍单例模式&#xff0c;包括遇到的问题、采用的解决方案、以及达到的效果。…...

运维人员的Python详细学习路线

以下是一条适合运维人员的Python详细学习路线&#xff1a; 一、基础入门阶段&#xff08;第1 - 2个月&#xff09; 环境搭建与基础语法&#xff08;第1个月&#xff09; 安装与配置 在运维常用的操作系统&#xff08;如Linux或Windows&#xff09;上安装Python。对于Linux系统…...

软件体系结构与设计模式

在软件开发中&#xff0c;软件体系结构和设计模式是两个至关重要的概念。它们帮助开发者设计出易于理解、可扩展、可维护的系统。尽管这两个概念密切相关&#xff0c;但它们分别关注系统的不同方面&#xff1a;软件体系结构关注的是系统整体结构的设计&#xff0c;而设计模式则…...

安徽省地图arcgis数据美化后mxd文件shp格式下载后内容测评

标题中的“安徽省地图arcgis数据美化后mxd文件shp格式”揭示了这个压缩包的内容是经过GIS处理的、针对安徽省地图数据。ArcGIS是一款由Esri公司开发的专业地理信息系统软件&#xff0c;用于处理、分析和展示地理空间数据。MXD文件是ArcGIS的项目文件&#xff0c;包含了地图布局…...

MySQL数据库备份与恢复策略

数据是企业和应用的核心资产,可靠的备份和恢复策略是确保数据安全性和业务连续性的关键。在本篇文章中,我们将详细介绍 MySQL 数据库的备份和恢复方法,包括逻辑备份、物理备份、自动化备份,以及常见问题的处理方法。 一、逻辑备份 逻辑备份是通过导出数据库的结构和数据生…...

go语言zero框架中教务crm系统的在职继承和离职交接的设计与实践

在GoZero中实现一个在职继承和离职交接的通用模块&#xff0c;涉及到顾问离职交接客户、领导离职交接审批单据等功能。为了使这个模块通用且易于扩展&#xff0c;我们可以分成几个部分&#xff1a; 1. **数据模型设计**&#xff1a;我们首先需要设计离职交接相关的数据模型。 …...

C# 设计模式(结构型模式):桥接模式

C# 设计模式&#xff08;结构型模式&#xff09;&#xff1a;桥接模式 在软件设计中&#xff0c;我们经常会遇到系统的变化频繁&#xff0c;或者需要灵活扩展功能的场景。这时&#xff0c;桥接模式&#xff08;Bridge Pattern&#xff09;便显得尤为重要。桥接模式是一个结构型…...

C# 设计模式(行为型模式):解释器模式

C# 设计模式&#xff08;行为型模式&#xff09;&#xff1a;解释器模式 (Interpreter Pattern) 什么是解释器模式&#xff1f; 解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为型设计模式&#xff0c;用于定义一种语言的语法表示&#xff0c;并提供一个解释…...

如何 cURL Elasticsearch:进入 Shell

作者&#xff1a;来自 Elastic Philipp Krenn Kibana 的控制台是开始使用 Elasticsearch 的 REST API 的最简单方法 - 语法突出显示、自动完成、格式化、导出 cURL、JavaScript 或 Python。而且你不必担心正确的端点、身份验证等。但是有时&#xff0c;如果 Kibana 不可用、你…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)

目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 ​编辑​编辑 UDP的特征 socke函数 bind函数 recvfrom函数&#xff08;接收函数&#xff09; sendto函数&#xff08;发送函数&#xff09; 五、网络编程之 UDP 用…...

海云安高敏捷信创白盒SCAP入选《中国网络安全细分领域产品名录》

近日&#xff0c;嘶吼安全产业研究院发布《中国网络安全细分领域产品名录》&#xff0c;海云安高敏捷信创白盒&#xff08;SCAP&#xff09;成功入选软件供应链安全领域产品名录。 在数字化转型加速的今天&#xff0c;网络安全已成为企业生存与发展的核心基石&#xff0c;为了解…...

2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版

1.题目描述 2.思路 当前的元素可以重复使用。 &#xff08;1&#xff09;确定回溯算法函数的参数和返回值&#xff08;一般是void类型&#xff09; &#xff08;2&#xff09;因为是用递归实现的&#xff0c;所以我们要确定终止条件 &#xff08;3&#xff09;单层搜索逻辑 二…...