【@EnableWebMvc的原理】

用途

启用SpringMvc 的 Java 配置类,代替 xml 格式的配置文件。

一、查看运用(注解 @EnableWebMvc ,实现 WebMvcConfigurer

@Component("com.ibicd")
@EnableWebMvc
public class AppConfig implements WebMvcConfigurer {public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {converters.add(new MappingJackson2HttpMessageConverter());}// 添加拦截器public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new WebContentInterceptor());}
}

二、@EnableWebMvc 的注解定义

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {}

1、查看 DelegatingWebMvcConfiguration 的配置

@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
//具体的代码...
}

2、查看 WebMvcConfigurationSupport

public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {//具体的代码...@Bean@Nullablepublic HandlerMapping viewControllerHandlerMapping(@Qualifier("mvcConversionService") FormattingConversionService conversionService,@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {ViewControllerRegistry registry = new ViewControllerRegistry(this.applicationContext);addViewControllers(registry);AbstractHandlerMapping handlerMapping = registry.buildHandlerMapping();if (handlerMapping == null) {return null;}PathMatchConfigurer pathConfig = getPathMatchConfigurer();if (pathConfig.getPatternParser() != null) {handlerMapping.setPatternParser(pathConfig.getPatternParser());}else {handlerMapping.setUrlPathHelper(pathConfig.getUrlPathHelperOrDefault());handlerMapping.setPathMatcher(pathConfig.getPathMatcherOrDefault());}//视图映射器设置拦截器handlerMapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));handlerMapping.setCorsConfigurations(getCorsConfigurations());return handlerMapping;}/*** 提供对共享处理程序拦截器的访问,用于配置HandlerMapping实例。* * <p>This method cannot be overridden; use {@link #addInterceptors} instead.*/protected final Object[] getInterceptors(FormattingConversionService mvcConversionService,ResourceUrlProvider mvcResourceUrlProvider) {if (this.interceptors == null) {InterceptorRegistry registry = new InterceptorRegistry();addInterceptors(registry); // 添加自定义的拦截器registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService));registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider));this.interceptors = registry.getInterceptors();}return this.interceptors.toArray();}/*** 重写此方法以添加用于控制器调用的Spring MVC拦截器的前置和后置处理。* @see InterceptorRegistry*/protected void addInterceptors(InterceptorRegistry registry) {}
}

在这里插入图片描述

3、查看 addInterceptors 的实现类情况(共2个)

在这里插入图片描述

4、查看 DelegatingWebMvcConfiguration 中的方法

@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();@Overrideprotected void addInterceptors(InterceptorRegistry registry) {this.configurers.addInterceptors(registry); // 调用 WebMvcConfigurerComposite 的 addInterceptors 方法}}

5、 查看 WebMvcConfigurerComposite

class WebMvcConfigurerComposite implements WebMvcConfigurer {private final List<WebMvcConfigurer> delegates = new ArrayList<>();// 查找调用此处的地方public void addWebMvcConfigurers(List<WebMvcConfigurer> configurers) {if (!CollectionUtils.isEmpty(configurers)) {this.delegates.addAll(configurers); // delegates 中添加所有的配置类}}@Overridepublic void addInterceptors(InterceptorRegistry registry) {for (WebMvcConfigurer delegate : this.delegates) { // this.delegates 为类中的 delegates delegate.addInterceptors(registry);  //调用每个配置类的 addInterceptors()}}}

6、在哪进行初始化 WebMvcConfigurer 的实现类?

目的就是查找调用 org.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite#addWebMvcConfigurers 的地方:

在这里插入图片描述

7、结论

根据上面的图可以知道:
我自己实现的AppConfig 配置类,使用了注解: @Component("com.ibicd")@EnableWebMvc,而在进行配置类扫描的时候,依赖注入的属性会自动注入,也就是在启动容器时会自动执行: org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#setConfigurers,然后再一次调用 addInterceptors()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/171763.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity的unity_ObjectToWorld里的每一列分别代表什么意思?换个方向反向理解-更简单

官方关键UnityObjectToWorldNormal&#xff08;&#xff09; 代码 从乐乐姐的书中得知&#xff0c;当我们在shader想获得法线&#xff0c;大概会这么些 o.wordDir UnityObjectToWorldNormal(i.normal) &#xff08;这行代码就包含了官方对“unity_ObjectToWorld”的终极理解…

在 Windows 用 Chrome System Settings 设置代理

在 Windows 用 Chrome System Settings 设置代理 贴心提示&#xff1a;在设置代理之前&#xff0c;请确保您已经安装了 浏览器。 &#x1f527; 设置代理的详细步骤如下&#xff1a; 打开 浏览器&#xff0c;输入 //settings/system 并回车。 在「系统和网络设置」页面中&am…

matlab Spongent算法

1、内容简介 略 5-可以交流、咨询、答疑 2、内容说明 Spongent 是一种轻量级 Hash 算法&#xff0c;其原理与“海绵”类似&#xff0c;分为“吸收” 和“榨取”两个阶段&#xff0c;所以又可以称之为“海绵结构”算法。 Hash 函数之所以有广泛的应用&#xff0c;是因为它具…

MySQL数据库#6

Python操作mysql 在使用Python连接mysql之前我们需要先下载一个第三方的模块 pymysql的模块&#xff0c;导入后再进行操作。 操作步骤&#xff1a;1. 先连接mysql host&#xff0c;port&#xff0c;charset&#xff0c;username password 库&#xff0c;等等。 import pymysql…

如何恢复u盘删除文件?2023最新分享四种方法恢复文件

U盘上删除的文件怎么恢复&#xff1f;使用U盘存储文件是非常方便的&#xff0c;例如&#xff1a;在办公的时候&#xff0c;会使用U盘来存储网络上查找到的资料、产品说明等。在学习的时候&#xff0c;会使用U盘来存储教育机构分享的教学视频、重点知识等。而随着U盘存储文件的概…

综合OA管理系统源码 OA系统源码

综合OA管理系统源码 OA系统源码 功能介绍&#xff1a; 编号&#xff1a;LQ10 一&#xff1a;系统管理 系统配置&#xff0c;功能模块&#xff0c;功能节点&#xff0c;权限角色&#xff0c;操作日志&#xff0c;备份数据&#xff0c;还原数据 二&#xff1a;基础数据 审批…

ExoPlayer架构详解与源码分析(7)——SampleQueue

系列文章目录 ExoPlayer架构详解与源码分析&#xff08;1&#xff09;——前言 ExoPlayer架构详解与源码分析&#xff08;2&#xff09;——Player ExoPlayer架构详解与源码分析&#xff08;3&#xff09;——Timeline ExoPlayer架构详解与源码分析&#xff08;4&#xff09;—…

Project Costs

/*** 初始化象棋的棋子&#xff0c;正常情况加载双方所有棋子&#xff0c;残局演示加载剩余棋子&#xff0c;按坐标位置摆放* * 【费用】* 因甲方要求产生工作量计算费用&#xff1b;新增、修改、删除需求* 因乙方生产缺陷工作量不计费用&#xff1b;缺陷、延误* * 来说个一个栗…

5 个编写高效 Makefile 文件的最佳实践

在软件开发过程中&#xff0c;Makefile是一个非常重要的工具&#xff0c;它可以帮助我们自动化构建、编译、测试和部署。然而&#xff0c;编写高效的Makefile文件并不是一件容易的事情。在本文中&#xff0c;我们将讨论如何编写高效的Makefile文件&#xff0c;以提高我们的开发…

unocss和tailwindcss css原子引擎

第一种tailwindcss&#xff1a; tailwindcss官网 https://tailwindcss.com/docs/grid-column 基本介绍及优点分析 Tailwind CSS 中文文档 - 无需离开您的HTML&#xff0c;即可快速建立现代网站 PostCss 处理 Tailwind Css 基本流程 PostCSS - 是一个用 JavaScript 工具和插…

Postman —— 配置环境变量

PostMan是一套比较方便的接口测试工具&#xff0c;但我们在使用过程中&#xff0c;可能会出现创建了API请求&#xff0c;但API的URL会随着服务器IP地址的变化而改变。 这样的情况下&#xff0c;如果每一个API都重新修改URL的话那将是非常的麻烦&#xff0c;所以PostMan中也提供…

使用ControlNet生成视频(Pose2Pose)

目录 ControlNet 介绍 ControlNet 14种模型分别是用来做什么的 ControlNet 运行环境搭建 用到的相关模型地址 ControlNet 介绍 ControlNet 是一种用于控制扩散模型的神经网络结构&#xff0c;可以通过添加额外的条件来实现对图像生成的控制。它通过将神经网络块的权重复制到…

从入门到精通:深入了解CSS中的Grid网格布局技巧和应用!

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! ​ 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一…

【tio-websocket】9、服务配置与维护—TioConfig

场景 我们在写 TCP Server 时,都会先选好一个端口以监听客户端连接,再创建N组线程池来执行相关的任务,譬如发送消息、解码数据包、处理数据包等任务,还要维护客户端连接的各种数据,为了和业务互动,还要把这些客户端连接和各种业务数据绑定起来,譬如把某个客户端绑定到一…

【shell】pis_monitor.sh

#!/bin/bashread -p "请输入要查询的PID:" pidecho "--------------------------------"echo "进程PID:$pid"p_arr("进程命令 11" "进程所属用户 1" "CPU占用率 2" "CPU内存占用率 4" "进程开始运…

深入浅出排序算法之简单选择排序

目录 1. 原理和执行流程 2. 代码实现 3. 性能分析 4. 双向选择排序&#xff08;了解&#xff09; 1. 原理和执行流程 选择排序包含了堆排序和简单选择排序。 每一次从无序区间选出最大&#xff08;或最小&#xff09;的一个元素&#xff0c;存放在无序区间的最后&#xff0…

Unity URP14.0 自定义后处理框架

目录 碎碎念一些基础CustomPostProcessing.csCustomPostProcessingFeature.csCustomPostProcessingPass.cs例子&#xff1a;BSC后处理shader&#xff08;BSC&#xff09;后处理cs脚本(BSC) 例子&#xff1a;ColorBlitPostProcessing.hlslColorBlit2.shaderColorBlit.cs文件 其他…

ab压力测试

标题相关概念 QPS&#xff0c;每秒查询 QPS&#xff1a;Queries Per Second意思是“每秒查询率”&#xff0c;是一台服务器每秒能够相应的查询次数&#xff0c;是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。 互联网中&#xff0c;作为域名系统服务器的机…

Python时间序列分析库介绍:statsmodels、tslearn、tssearch、tsfresh

时间序列分析在金融和医疗保健等领域至关重要&#xff0c;在这些领域&#xff0c;理解随时间变化的数据模式至关重要。在本文中&#xff0c;我们将介绍四个主要的Python库——statmodels、tslearn、tssearch和tsfresh——每个库都针对时间序列分析的不同方面进行了定制。这些库…