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

Spring MVC 五:DispatcherServlet初始化之 mvc:annotation-driven

通过xml方式初始化DispatcherServlet时,xml文件中可以配置:

<mvc:annotation-driven />

或:

   <mvc:annotation-driven ><!--设置响应输出字符集--><mvc:message-converters><bean class="org.springframework.http.converter.StringHttpMessageConverter"><property name="supportedMediaTypes"><list><value>text/html;charset=utf-8</value></list></property></bean></mvc:message-converters></mvc:annotation-driven>

表示对MVC注解的支持。

该标签的解析工作最终会由AnnotationDrivenBeanDefinitionParser的parse方法完成,parse方法主要完成以下工作

  1. 注册RequestMappingHandlerMapping的beanDefinition到WebApplication容器
  2. 注册RequestMappingHandlerAdapter的beanDefinition到WebApplication容器,同时从xml文件解析其messageConverters的定义(这也是xml文件中messageConverters生效的原因)
  3. 注册ExceptionHandlerExceptionResolver的beanDefinition到WebApplication容器
  4. 注册ResponseStatusExceptionResolver的beanDefinition到WebApplication容器
  5. 注册DefaultHandlerExceptionResolver的beanDefinition到WebApplication容器

之后在容器refresh的过程中根据beanDefinition创建对应的bean。

之后,在DispatcherServlet初始化的过程中,通过initStrategies初始化SpringMVC的相关“特殊类型的Bean”:

	protected void initStrategies(ApplicationContext context) {initMultipartResolver(context);initLocaleResolver(context);initThemeResolver(context);initHandlerMappings(context);initHandlerAdapters(context);initHandlerExceptionResolvers(context);initRequestToViewNameTranslator(context);initViewResolvers(context);initFlashMapManager(context);}

比如initHandlerMappings方法:

private void initHandlerMappings(ApplicationContext context) {this.handlerMappings = null;if (this.detectAllHandlerMappings) {// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.//首先通过beanFactoryUtils从Spring容器中,通过类型获取Map<String, HandlerMapping> matchingBeans =BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);//如果从容器中获取到了bean,放入到handlerMappings中if (!matchingBeans.isEmpty()) {this.handlerMappings = new ArrayList<>(matchingBeans.values());// We keep HandlerMappings in sorted order.AnnotationAwareOrderComparator.sort(this.handlerMappings);}}else {try {//通过名字和类型从容器获取HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);this.handlerMappings = Collections.singletonList(hm);}catch (NoSuchBeanDefinitionException ex) {// Ignore, we'll add a default HandlerMapping later.}}// Ensure we have at least one HandlerMapping, by registering// a default HandlerMapping if no other mappings are found.if (this.handlerMappings == null) {//从容器中没有获取到,才调用getDefaultStrategies获取默认的、dispatcherServlet.properties文件中定义的this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);if (logger.isTraceEnabled()) {logger.trace("No HandlerMappings declared for servlet '" + getServletName() +"': using default strategies from DispatcherServlet.properties");}}}

如果xml文件中不配置<mvc:annotation-driven />,也没有 <mvc:default-servlet-handler />,则Spring容器中就不会有对应的bean,这种情况下,才通过调用getDefaultStrategies方法,读取DispatcherServlet.properties文件获取该文件定义的默认HandlerMappings,完成创建,当然,创建后也会放入Spring容器:

	protected Object createDefaultStrategy(ApplicationContext context, Class<?> clazz) {return context.getAutowireCapableBeanFactory().createBean(clazz);}
DefaultServletHandlerBeanDefinitionParser

xml文件中如果配置了 <mvc:default-servlet-handler />,SpringMVC启动时解析 <mvc:default-servlet-handler />标签过程中会调用DefaultServletHandlerBeanDefinitionParser,其parse方法会将SimpleUrlHandlerMapping以及BeanNameUrlHandlerMapping注入到WebApplicationContext容器中,目的是通过SimpleUrlHandlerMapping来处理"/**"请求(转交给DefaultServletHttpRequestHandler)。

这个处理有个副作用:由于SimpleUrlHandlerMapping、BeanNameUrlHandlerMapping作为handlerMappings注入到容器中,分析DispatcherServlet的初始化方法initHandlerMappings的源码可知:DispatcherServlet.properties文件中默认的RequestMappingHandlerMapping不会被注入!而RequestMappingHandlerMapping是具体负责SpringMVC注解解释的,没有了RequestMappingHandlerMapping,类似@Controller等SpringMVC注解就不会生效。

所以,其实SpringMVC默认情况下天生是可以支持SpringMVC注解的,只不过是 <mvc:default-servlet-handler />往往不可避免的需要配置(因为项目中总有静态资源需要展示),但是加了 <mvc:default-servlet-handler />会导致SpringMVC的注解失效!

因此导致了,正常的SpringMVC项目的以下两项配置往往需要成对出现:

 <mvc:annotation-driven /><mvc:default-servlet-handler />

上一篇 Spring MVC 十:异常处理

相关文章:

Spring MVC 五:DispatcherServlet初始化之 mvc:annotation-driven

通过xml方式初始化DispatcherServlet时&#xff0c;xml文件中可以配置&#xff1a; <mvc:annotation-driven />或&#xff1a; <mvc:annotation-driven ><!--设置响应输出字符集--><mvc:message-converters><bean class"org.springframework.…...

uniapp EventChannel 页面跳转参数事件传递navigateBack,navigateTo 成功后通知事件区别

问题&#xff1a;navigateBack&#xff08;&#xff09;emit事件在onload()监听不到 从A页面跳转到B页面&#xff0c;在B点击产生数据后&#xff0c;跳转回到A&#xff0c;并告诉A点击的数据是什么&#xff0c;使用&#xff1a; navigateBack&#xff08;&#xff09;。 &…...

【C++ Primer Plus学习记录】指针——使用delete释放内存

当需要内存时&#xff0c;可以使用new来请求&#xff0c;使用完内存后&#xff0c;可以使用delete将其归还给内存池。 归还或释放&#xff08;free&#xff09;的内存可供程序的其他部分使用。 使用delete时&#xff0c;后面要加上指向内存块的指针&#xff08;这些内存块最初…...

2023 NOIP A层联测9 - 风信子 题解

思路 我们可以考虑设 f l 0 , r 0 , l 1 , r 1 f_{l_0,r_0,l_1,r_1} fl0​,r0​,l1​,r1​​ 表示最大的 a l − a r a_l-a_r al​−ar​&#xff0c;其中 l ∈ [ l 0 , r 0 ] l\in [l_0,r_0] l∈[l0​,r0​]&#xff0c; r ∈ [ l 1 , r 1 ] r\in [l_1, r_1] r∈[l1​,r1​…...

岩土工程安全监测无线振弦采集仪在无线组网的关键要点

岩土工程安全监测无线振弦采集仪在无线组网的关键要点 岩土工程是一种奇特而又极其重要的工程。它涉及到土地、岩石、气候等等因素&#xff0c;需要重视安全因素。而无线振弦采集仪作为一种常用的监测设备&#xff0c;可以采集岩土工程中的振动数据&#xff0c;从而确保工程的…...

代码随想录Day14 LeetCodeT110平衡二叉树 T257二叉树的所有路径 T404 左叶子之和

以下思路来自于: 代码随想录 (programmercarl.com) LeetCode T110 平衡二叉树 题目链接:110. 平衡二叉树 - 力扣&#xff08;LeetCode&#xff09; 题目思路 前面我们说过了,求二叉树的深度我们应该使用前序遍历,求二叉树的高度我们应该使用后序遍历,因为后序遍历可以将子树的…...

C语言自定义类型_枚举联合(3)

目录 枚举 什么是枚举类型&#xff1f; 枚举的声明 枚举的定义 枚举的优点 枚举的使用 联合&#xff08;共用体&#xff09; 什么是联合呢&#xff1f; 联合类型的定义 联合的特点 联合使用 联合大小的计算 联合的应用 今天接着我们来结束自定义类型。&#x1f19…...

asp.net网上销售系统VS开发mysql数据库web结构c#编程Microsoft Visual Studio计算机毕业设计

一、源码特点 asp.net 网上销售系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为mysql&#xff0c;使用c#语言开发 aspnet 网上销售系统1 二、功能介绍 前台功能…...

【Windows】RPC调用过程实例详解

概述&#xff1a;windows 创建 RPC调用过程实例详解 参考文章&#xff1a;Remote procedure call (RPC)&#xff08;远程过程调用 (RPC)&#xff09; - Win32 apps | Microsoft Learn 文章目录 0x01、生成 UUID 和模版(IDL)文件0x02、添加 acf 文件0x03、编译 idl 文件0x04、客…...

动手学强化学习第2章多臂老虎机

2.1简介 多臂老虎机问题可以被看作简化版的强化学习问题。但是其只有动作和奖励没有状态信息&#xff0c;算是简化版的强化学习问题。 2.2问题介绍 2.2.1问题定义 在多臂老虎机(MAB)问题中&#xff0c;有一个有K根拉杆的老虎机&#xff0c;拉动每一根拉杆都对应一个关于奖励…...

钡铼BL124EC实现EtherCAT转Ethernet/IP的优势

钡铼技术的BL124EC是一款用于将EtherCAT从站转换为Ethernet/IP从站的网关设备。它是钡铼技术开发的高性能、可靠的工业自动化通信解决方案之一。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; BL124EC网关可以应用于多种工业自动化场景&#xff0c;以下…...

使用IntelliJ Idea必备的插件!

趁手的工具让开发事半功倍&#xff0c;好用的IDEA插件让效率加倍。 今天给大家分享几个优秀的IDEA插件。 插件安装 首先得知道在IDEA哪安装插件&#xff1f; 点击File---->Settings---->找到Plugins标签&#xff0c;即可搜索想要的插件进行安装了。 现在来看下有哪些值…...

代码随想录算法训练营第23期day19| 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

目录 一、&#xff08;leetcode 654&#xff09;最大二叉树 二、&#xff08;leetcode 617&#xff09;合并二叉树 三、&#xff08;leetcode 700&#xff09;二叉搜索树中的搜索 四、&#xff08;leetcode 98&#xff09;验证二叉搜索树 一、&#xff08;leetcode 654&…...

第四章 字符串part02 28. 实现strStr() 459. 重复的子字符串

第四章 字符串part02 28. 实现strStr() 459. 重复的子字符串 一、28. 实现strStr() 题目链接&#xff1a;https://leetcode.cn/problems/repeated-substring-pattern/ 题目介绍&#xff1a; 给定一个非空的字符串 s &#xff0c;检查是否可以通过由它的一个子串重复多次构成。…...

设计模式 - 状态模式

目录 一. 前言 二. 实现 一. 前言 状态模式&#xff08;State Pattern&#xff09;&#xff1a;它主要用来解决对象在多种状态转换时&#xff0c;需要对外输出不同的行为的问题。状态和行为是一一对应的&#xff0c;状态之间可以相互转换。当一个对象的内在状态改变时&#x…...

【vim 学习系列文章 9 -- .vim 脚本文件开发学习】

文章目录 .vimrc 介绍.vim 脚本文件开发 .vimrc 介绍 在Vim中&#xff0c;你可以将一系列的Vim命令和设置写入一个脚本文件中&#xff0c;并使用:source命令来运行它。这种脚本文件通常被称为vimrc文件&#xff0c;因为它的默认名称是.vimrc。通常&#xff0c;我们将这个文件放…...

NAT模式和桥接模式的区别

NAT模式和桥接模式的区别 NAT模式和桥接模式都是虚拟机网络配置的两种方式&#xff0c;主要区别在于虚拟机与外部网络交互的方式不同。 NAT&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;模式&#xff1a;在这种模式下&#xff0c;虚拟机和宿主…...

应对出海安全合规挑战,兆珑科技为什么选择了亚马逊云科技?

在中国企业出海进程中&#xff0c;安全合规是企业面临的首要挑战。尤其是当企业业务涉及金融相关领域时&#xff0c;面临着最为严苛的安全合规要求。 深圳兆珑科技有限公司是一家全球化的物联网生态企业&#xff0c;其业务覆盖100多个国家和地区&#xff0c;在欧洲、南美、亚太…...

Allegro基本规则设置指导书之Spacing规则设置

进入规则设置界面 1.设置Line 到其他的之间规则: 2.设置Pins 到其他的之间规则: 3.设置Vias 到其他的之间规则:...

使用【Blob、Base64】两种方式显示【文本、图片、视频】 使用 video 组件播放视频

Blob 显示 Blob 对象的类型是由 MIME 类型&#xff08;Multipurpose Internet Mail Extensions&#xff09;来确定的。MIME 类型是一种标准&#xff0c;用于表示文档、图像、音频、视频等多媒体文件的类型。以下是一些常见的 Blob 对象类型&#xff1a; text/plain&#xff1…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...