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࿱…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...