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方法主要完成以下工作
- 注册RequestMappingHandlerMapping的beanDefinition到WebApplication容器
- 注册RequestMappingHandlerAdapter的beanDefinition到WebApplication容器,同时从xml文件解析其messageConverters的定义(这也是xml文件中messageConverters生效的原因)
- 注册ExceptionHandlerExceptionResolver的beanDefinition到WebApplication容器
- 注册ResponseStatusExceptionResolver的beanDefinition到WebApplication容器
- 注册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时,xml文件中可以配置: <mvc:annotation-driven />或: <mvc:annotation-driven ><!--设置响应输出字符集--><mvc:message-converters><bean class"org.springframework.…...
uniapp EventChannel 页面跳转参数事件传递navigateBack,navigateTo 成功后通知事件区别
问题:navigateBack()emit事件在onload()监听不到 从A页面跳转到B页面,在B点击产生数据后,跳转回到A,并告诉A点击的数据是什么,使用: navigateBack()。 &…...
【C++ Primer Plus学习记录】指针——使用delete释放内存
当需要内存时,可以使用new来请求,使用完内存后,可以使用delete将其归还给内存池。 归还或释放(free)的内存可供程序的其他部分使用。 使用delete时,后面要加上指向内存块的指针(这些内存块最初…...
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,其中 l ∈ [ l 0 , r 0 ] l\in [l_0,r_0] l∈[l0,r0], r ∈ [ l 1 , r 1 ] r\in [l_1, r_1] r∈[l1,r1…...
岩土工程安全监测无线振弦采集仪在无线组网的关键要点
岩土工程安全监测无线振弦采集仪在无线组网的关键要点 岩土工程是一种奇特而又极其重要的工程。它涉及到土地、岩石、气候等等因素,需要重视安全因素。而无线振弦采集仪作为一种常用的监测设备,可以采集岩土工程中的振动数据,从而确保工程的…...
代码随想录Day14 LeetCodeT110平衡二叉树 T257二叉树的所有路径 T404 左叶子之和
以下思路来自于: 代码随想录 (programmercarl.com) LeetCode T110 平衡二叉树 题目链接:110. 平衡二叉树 - 力扣(LeetCode) 题目思路 前面我们说过了,求二叉树的深度我们应该使用前序遍历,求二叉树的高度我们应该使用后序遍历,因为后序遍历可以将子树的…...
C语言自定义类型_枚举联合(3)
目录 枚举 什么是枚举类型? 枚举的声明 枚举的定义 枚举的优点 枚举的使用 联合(共用体) 什么是联合呢? 联合类型的定义 联合的特点 联合使用 联合大小的计算 联合的应用 今天接着我们来结束自定义类型。Ἑ…...
asp.net网上销售系统VS开发mysql数据库web结构c#编程Microsoft Visual Studio计算机毕业设计
一、源码特点 asp.net 网上销售系统 是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为mysql,使用c#语言开发 aspnet 网上销售系统1 二、功能介绍 前台功能…...
【Windows】RPC调用过程实例详解
概述:windows 创建 RPC调用过程实例详解 参考文章:Remote procedure call (RPC)(远程过程调用 (RPC)) - Win32 apps | Microsoft Learn 文章目录 0x01、生成 UUID 和模版(IDL)文件0x02、添加 acf 文件0x03、编译 idl 文件0x04、客…...
动手学强化学习第2章多臂老虎机
2.1简介 多臂老虎机问题可以被看作简化版的强化学习问题。但是其只有动作和奖励没有状态信息,算是简化版的强化学习问题。 2.2问题介绍 2.2.1问题定义 在多臂老虎机(MAB)问题中,有一个有K根拉杆的老虎机,拉动每一根拉杆都对应一个关于奖励…...
钡铼BL124EC实现EtherCAT转Ethernet/IP的优势
钡铼技术的BL124EC是一款用于将EtherCAT从站转换为Ethernet/IP从站的网关设备。它是钡铼技术开发的高性能、可靠的工业自动化通信解决方案之一。 添加图片注释,不超过 140 字(可选) BL124EC网关可以应用于多种工业自动化场景,以下…...
使用IntelliJ Idea必备的插件!
趁手的工具让开发事半功倍,好用的IDEA插件让效率加倍。 今天给大家分享几个优秀的IDEA插件。 插件安装 首先得知道在IDEA哪安装插件? 点击File---->Settings---->找到Plugins标签,即可搜索想要的插件进行安装了。 现在来看下有哪些值…...
代码随想录算法训练营第23期day19| 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树
目录 一、(leetcode 654)最大二叉树 二、(leetcode 617)合并二叉树 三、(leetcode 700)二叉搜索树中的搜索 四、(leetcode 98)验证二叉搜索树 一、(leetcode 654&…...
第四章 字符串part02 28. 实现strStr() 459. 重复的子字符串
第四章 字符串part02 28. 实现strStr() 459. 重复的子字符串 一、28. 实现strStr() 题目链接:https://leetcode.cn/problems/repeated-substring-pattern/ 题目介绍: 给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。…...
设计模式 - 状态模式
目录 一. 前言 二. 实现 一. 前言 状态模式(State Pattern):它主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转换。当一个对象的内在状态改变时&#x…...
【vim 学习系列文章 9 -- .vim 脚本文件开发学习】
文章目录 .vimrc 介绍.vim 脚本文件开发 .vimrc 介绍 在Vim中,你可以将一系列的Vim命令和设置写入一个脚本文件中,并使用:source命令来运行它。这种脚本文件通常被称为vimrc文件,因为它的默认名称是.vimrc。通常,我们将这个文件放…...
NAT模式和桥接模式的区别
NAT模式和桥接模式的区别 NAT模式和桥接模式都是虚拟机网络配置的两种方式,主要区别在于虚拟机与外部网络交互的方式不同。 NAT(Network Address Translation,网络地址转换)模式:在这种模式下,虚拟机和宿主…...
应对出海安全合规挑战,兆珑科技为什么选择了亚马逊云科技?
在中国企业出海进程中,安全合规是企业面临的首要挑战。尤其是当企业业务涉及金融相关领域时,面临着最为严苛的安全合规要求。 深圳兆珑科技有限公司是一家全球化的物联网生态企业,其业务覆盖100多个国家和地区,在欧洲、南美、亚太…...
Allegro基本规则设置指导书之Spacing规则设置
进入规则设置界面 1.设置Line 到其他的之间规则: 2.设置Pins 到其他的之间规则: 3.设置Vias 到其他的之间规则:...
使用【Blob、Base64】两种方式显示【文本、图片、视频】 使用 video 组件播放视频
Blob 显示 Blob 对象的类型是由 MIME 类型(Multipurpose Internet Mail Extensions)来确定的。MIME 类型是一种标准,用于表示文档、图像、音频、视频等多媒体文件的类型。以下是一些常见的 Blob 对象类型: text/plain࿱…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...
