springmvc源码笔记-HandlerMapping注入
在springmvc中,如何根据url找到controller以及对应方法,依赖的是HandlerMapping接口的getHandler方法
在spring容器中默认注册的HandlerMapping有以下五种:
- RequestMappingHandlerMapping
- BeanNameUrlHandlerMapping
- SimpleUrlHandlerMapping
- RouterFunctionMapping
- WelcomePageHandlerMapping
本文主要探索spring和springboot启动过程中RequestMappingHandlerMapping的注入
Spring中RequestMappingHandlerMapping的注入
环境
springmvc版本:5.1.9.RELEASE
过程
在springmvc中,使用注解需要在xml了加入注解声明
<!-- 注解扫描 -->
<context:component-scan base-package="com.xiaofan"/>
<!--使用mvc注解声明 -->
<mvc:annotation-driven/>
启动web服务器,我用的是tomcat8
spring启动,注册BeanDefinition,
spring会扫描xml文件,将配置文件中的bean信息注册成BeanDefinition,当发现springmvc的xml配置文件中有annotation-driven标签时,会调用AnnotationDrivenBeanDefinitionParser来解析该标签
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext context) {
...
// 前面省略代码
RootBeanDefinition handlerMappingDef = new RootBeanDefinition(RequestMappingHandlerMapping.class);
handlerMappingDef.setSource(source);
handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
handlerMappingDef.getPropertyValues().add("order", 0);
handlerMappingDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager); if (element.hasAttribute("enable-matrix-variables")) {
Boolean enableMatrixVariables = Boolean.valueOf(element.getAttribute("enable-matrix-variables"));
handlerMappingDef.getPropertyValues().add("removeSemicolonContent", !enableMatrixVariables);
} configurePathMatchingProperties(handlerMappingDef, element, context);
// String HANDLER_MAPPING_BEAN_NAME = RequestMappingHandlerMapping.class.getName()
readerContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef);
// 后面省略代码
...
return null;
}
spring将BeanDefinition通过反射实例化成bean注入到容器中
那么问题来了,如果没有mvc:annotation-driven标签,RequestMappingHandlerMapping还会被注入到spring容器中吗?
答:会的,前提是xml中没有配置任何一个HandlerMapping。
过程如下:
在启动过程中,会调用DispatcherServlet的init()方法(我也不知道是在哪个步骤调用的,希望知道的大佬告知,不胜感激)
DispatcherServlet#onRefresh → DispatcherServlet#initStrategies → DispatcherServlet#initHandlerMappings
private void initHandlerMappings(ApplicationContext context) {
...
// 前面省略代码
// 当没有配置任何handlerMapping时,则使用默认的handlerMapping
if (this.handlerMappings == null) {
// 从DispatcherServlet.properties拿org.springframework.web.servlet.HandlerMapping
// 所以默认的有BeanNameUrlHandlerMapping和RequestMappingHandlerMapping
// 最终还是调用BeanFactory#createBean()生成实例
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
if (logger.isTraceEnabled()) {
logger.trace("No HandlerMappings declared for servlet '" + getServletName() +
"': using default strategies from DispatcherServlet.properties");
}
}
}
SpringBoot中RequestMappingHandlerMapping的注入
在springboot中的注入,依赖的是springboot的自动装配
环境
Springboot版本:2.4.3
过程
spring-boot-autoconfigure包下的spring.factories中有WebMvcAutoConfiguration
WebMvcAutoConfiguration的内部类EnableWebMvcConfiguration#requestMappingHandlerMapping()
@Bean
@Primary
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping(
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
// Must be @Primary for MvcUriComponentsBuilder to work
return super.requestMappingHandlerMapping(contentNegotiationManager, conversionService,
resourceUrlProvider);
}
问题
在spring环境中,DispatcherServlet的init方法在web服务器启动过程中就被调用了,而在springboot环境中,只有在DispatcherServlet被第一次调用的时候,才会执行init方法,有同学知道原因吗?不胜感激
springmvc源码笔记-HandlerMapping注入的更多相关文章
- springmvc源码笔记-RequestMappingHandlerMapping
下图是springmvc的执行流程 图片来源:https://www.jianshu.com/p/8a20c547e245 DispatcherServlet根据url定位到Controller和方法 ...
- SpringMVC源码解读 - HandlerMapping
SpringMVC在请求到handler处理器的分发这步是通过HandlerMapping模块解决的.handlerMapping 还处理拦截器. 先看看HandlerMapping的继承树吧 可以大 ...
- springMVC源码分析--HandlerMapping(一)
HandlerMapping的工作就是为每个请求找到合适的请求找到一个处理器handler,其实现机制简单来说就是维持了一个url到Controller关系的Map结构,其提供的实际功能也是根据req ...
- springMVC源码笔记
springMVC 设计总览 下图来源:https://www.cnblogs.com/fangjian0423/p/springMVC-directory-summary.html 下图来源:htt ...
- SpringMVC源码解读 - HandlerMapping - RequestMappingHandlerMapping请求分发
AbstractHandlerMethodMapping实现接口getHandlerInternal,定义查找流程 RequestMappingInfoHandlerMapping根据RequestM ...
- SpringMVC源码解读 - HandlerMapping - AbstractUrlHandlerMapping系列request分发
AbstractHandlerMapping实现HandlerMapping接口定的getHandler 1. 提供getHandlerInternal模板方法给子类实现 2. 如果没有获取Handl ...
- SpringMVC源码解读 - HandlerMapping - SimpleUrlHandlerMapping初始化
摘要: SimpleUrlHandlerMapping只是参与Handler的注册,请求映射时由AbstractUrlHandlerMapping搞定. 初始化时,通过setMappings(Prop ...
- springmvc源码笔记-HandlerMethodReturnValueHandler
返回值解析器 用于对controller的返回值进行二次处理 结构 // 返回值解析器 public interface HandlerMethodReturnValueHandler { // 判断 ...
- SpringMVC源码解读 - HandlerMapping - RequestMappingHandlerMapping初始化
RequestMappingHandlerMapping ,用于注解@Controller,@RequestMapping来定义controller. @Controller @RequestMapp ...
随机推荐
- .NET性能优化-使用ValueStringBuilder拼接字符串
前言 这一次要和大家分享的一个Tips是在字符串拼接场景使用的,我们经常会遇到有很多短小的字符串需要拼接的场景,在这种场景下及其的不推荐使用String.Concat也就是使用+=运算符. 目前来说官 ...
- 806. Number of Lines To Write String - LeetCode
Question 806. Number of Lines To Write String Solution 思路:注意一点,如果a长度为4,当前行已经用了98个单元,要另起一行. Java实现: p ...
- 亿信BI——EXCEL组件使用流程
功能模块: 用户点击"excel输入"模块进行excel文件导入操作,excel导入页面的顶部导航栏包括基本属性.文件设置.格式设置和字段列表四部分. 基础属性: 在基本属性模块部 ...
- SMFL 教程&个人笔记
本文大部分来自官方教程的Google翻译 但是加了一点点个人的理解和其他相关知识 转载请注明 原文链接 :https://www.cnblogs.com/Multya/p/16273753.html ...
- resttemplate 请求方式详解
get 普通请求: restemplate.getForEntity(url,String.class).getBody(); get 导出请求: restemplate.getForEntity(u ...
- React设置proxy后依旧报CROS错误
1.判断表单数据是否为后端接收的类型 POST GET2.axios自动转换问题 手动添加标头这份表单数据包括了files (二进制数据)而标头显示是JSON格式 不符 所以报CROS 更多文章请移步 ...
- .NET C#基础(5):结构体 - 高性能代码的基石
0. 文章目的 本文面向有一定.NET C#基础知识的学习者,介绍C#中结构体定义.使用以及特点. 1. 阅读基础 了解C#基本语法 了解.NET中的栈与托管堆 2. 值类型 2.1 .N ...
- 解决python无法打开谷歌浏览器问题
python+selenium 打开浏览器网页时可能会出现两种情况, 一.python 初次打开浏览器未进行安装浏览器控制插件, 二.python 能打开浏览器的情况下,突然有一天发现无法打开并报错新 ...
- NOI Online 2022 一游
NOI Online 2022 一游 TG 啊,上午比提高,根据去年的经验,题目配置估计那至少一黑 所以直接做 1 题即可.(确信) 总体:估分 140,炸了但没完全炸 奇怪的过程 开题:3 2 1 ...
- 使用PowerShell下载文件
更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月12日. 使用Invoke-WebRequest指令下载文件 [Net.ServicePointManager]::Securit ...