SpringMvc之映射器HandlerMapping

简介

        在springmvc的处理流程中,第一步就是查询请求对应的映射器,然后组装成处理器链处理请求,本文意在梳理该过程

重要实现

        HandlerMapping是一个接口,该接口用于通过HttpServletRequest寻找对应的处理器,接口介绍如下:

该接口只有一个抽象方法:

  该接口的几个重要子类和关系图如下:

在HandlerMapping的直接子类:AbstractHandlerMapping中有定义核心方法:

后续的各种HandlerMapping均是扩展该接口实现自身逻辑,以下以最常用的关于注解:@RestController,@Controller,@RequestMapping使用的处理器映射关系为例做源码分析

RequestMappingHandlerMapping

类的UML图如下:

由类的UML图可知,RequestMappingHandlerMapping集成了AbstractHandlerMethodMapping,

而AbstractHandlerMethodMapping类定义如下:

所以:RequestMappingHandlerMapping类也实现了InitializingBean,在类的初始化创建完成之后,会做相应的初始化操作,具体的代码如下:

方法initHandlerMethods()即是初始化handler方法,调用processCandidateBean完成ioc的bean对象处理:

其中IsHandler方法用于检测该bean对象是否符合条件,实现交RequestMappingHandlerMapping实现

判断标准就是该类是否有标注@Controller(@RestController注解有标注@Controller)注解或者@RequestMapping注解

符合条件的类继续往下对方法做探测:

对该类的每个方法均做检测,看看是否符合条件,而符合条件的方法检测标准即是是否有标注@RequestMapping注解(@GetMapping等注解均被@RequestMapping注解标注),这里具体的实现逻辑在org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#getMappingForMethod

当所有符合条件的方法检测完成之后,需要对对应的方法和组装的RequestMappingInfo(可以是其他对象)完成注册操作

MappingRegistry

        该类是AbstractHandlerMethodMapping的内部类,该类中定义多个缓存对象,用于存放各种映射关系,如下图所示:

其中有两个重要的缓存对象:

mappingLookup:用于存放RequestMappingInfo(可以是其他对象)和HandlerMethod的映射关系
urlLookup:用于存放请求路径和RequestMappInfo(可以是其他对象)的映射关系

至此:RequestMappingHandlerMapping的启动流程分析完毕,总结如下:

RequestMappingHandlerMapping在初始化完成之后,调用父类AbstractHandlerMethodMapping的initHandlerMethods方法,该方法会检测ioc中所有符合条件的(@Controller@RequestMapping的类),然后依次检测该类中标注了@RequestMapping的方法,然后组装成RequestMappingInfo对象,将方法和RequestMappingInfo的映射关系注册到MappingRegistry的两个缓存对象:

mappingLookup、urlLookup中,完成注册操作

而在实际请求中则是以上过程的逆过程,相关源码感兴趣的同学可以自行调试分析

自定义端点源码分析

在springboot actuator中有很多的监控信息可以通过暴露"端点"的方法让外部获取应用的信息,而端点的暴露即和以上过程大体相当

在图3所示的springboot actuator的自定义端点是通过WebMvcEndpointHandlerMapping暴露的

从图3的类继承图可知:WebMvcEndpointHandlerMapping继承子AbstractHandlerMethodMapping

在类初始化完成之后,一样会调用afterPropertiesSet,AbstractWebMvcEndpointHandlerMapping重写了initHandlerMethods方法,具体的逻辑如下:

在这里是通过构建WebOperation暴露端点,同样的,将相关信息(RequestMappingInfo)和HandlerMethod的映射关系注册到AbstractHanderMethodMapping的内部类MappingRegistry中完成初始化过程

以下简单的梳理一下Actuator暴露端点的过程

1 spring-boot-starter-actuator依赖引入了依赖spring-boot-actuator-autoconfigure,通过springboot的自动装配原理,会读取spring.factories的类

2 WebMvcEndpointManagementContextConfiguration配置类中通过条件配置引入了WebMvcEndpointHandlerMapping对象

3 WebMvcEndpointHandlerMapping执行初始化流程,完成RequestMappingInfo和HandlerMethod的映射注册

以下是引入springboot-actuator的能暴露的Endpoint类实现

具体的信息获取逻辑感兴趣的可以自行调试

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

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

相关文章

攻防世界逆向刷题

阅读须知: 探索者安全团队技术文章仅供参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作,由于传播、利用本公众号所提供的技术和信息而造成的任何直接或者间接的后果及损失,均由使用者 本人负责,作者不为此承担任何责任,如…

使用`scipy.stats.wasserstein_distance`来计算两个一维分布之间的Earth Mover‘s Distance (EMD)距离

在Python中,计算Earth Mover’s Distance (EMD)通常使用scipy库中的scipy.stats.wasserstein_distance函数,该函数计算的是Wasserstein距离,它与EMD非常相似,都是用来衡量两个分布之间的距离。 以下是一个简单的Python程序例子&a…

超好用的快捷回复软件

随着直播经济和短视频平台的兴起,品牌营销阵地不再局限于传统的电商巨头——淘宝、天猫、京东和拼多多,越来越多的品牌正积极布局快手、抖音等新晋电商平台,同步打造社群矩阵以拓宽产品推广渠道。这种多维度的市场渗透策略有力地提升了品牌的…

C语言看完我这篇编译与链接就够啦!!!

1. 前言 Hello!大家好我是小陈,今天来给大家介绍最详细的C语言编译与链接。 2. 编译和链接 我们通常用的编译器,比如Visual Sudio,这样的IDE(集成开发环境)一般将编译和链接的过程一步完成,通常将这这种编译和链接合…

算法(6)KMP+trie

KMP: 最浅显易懂的 KMP 算法讲解_哔哩哔哩_bilibili 该视频使用python书写代码,不会python的小伙伴也可以看看了解kmp的大致思路。 问题描述: kmp:字符串匹配算法,用来找一个长字符串中出现了几次小字符串&#xf…

【机器学习300问】54、如何找到有效的组合特征?

一、为什么需要去寻找有效的组合特征? 因为并不是所有的特征组合都会意义,都能带来价值。 例如在房价预测场景中,卧室数量和浴室数量的比值有意义,但房屋面积与建造年份相组合作为新的组合特征,可能就没有实际含义&…

【ORB-SLAM3】在 Ubuntu20.04 上编译 ORM-SLAM3 并使用 D435i、EuRoC 和 TUM-VI 运行测试

【ORB-SLAM3】在 Ubuntu20.04 上编译 ORM-SLAM3 并使用 D435i、EuRoC 和 TUM-VI 运行测试 1 Prerequisites1.1 C11 or C0x Compiler1.2 Pangolin1.3 OpenCV1.4 Eigen3 2 安装 Intel RealSense™ SDK 2.02.1 测试设备2.2 编译源码安装 (Recommend)2.3 预编译包安装 3 编译 ORB-S…

PTA L2-037 包装机

一种自动包装机的结构如图 1 所示。首先机器中有 N 条轨道,放置了一些物品。轨道下面有一个筐。当某条轨道的按钮被按下时,活塞向左推动,将轨道尽头的一件物品推落筐中。当 0 号按钮被按下时,机械手将抓取筐顶部的一件物品&#x…

07、Lua 流程控制

Lua 流程控制 Lua 流程控制控制结构语句 Lua 流程控制 Lua编程语言流程控制语句通过程序设定一个或多个条件语句来设定。在条件为 true 时执行指定程序代码,在条件为 false 时执行其他指定代码。 以下是典型的流程控制流程图: 控制结构的条件表达式结…

vscode c++环境配置

1.基础软件安装 安装Visual Studio Code. 安装C拓展。点击在vscode界面最左侧的Extensions图标(打开快捷键:ctrlshiftX),搜索“C/C”,点击进行安装。 确保已安装gcc. 一般ubuntu系统会预装gcc.在终端窗口中输入如下…

查立得源码如何去除版权

最近发现很多人百度:查立得源码如何去除版权。 每个源代码/软件都是有版权的,无法去除,我们也得尊重知识产权/劳动成果。 可以去除/修改的是:页面显示的版权信息,查立得底部信息均可自定义(一般conn.php可修改)。 另&#xff1…

Linux-2 Linux的权限

目录 1.什么是权限? 2.权限的本质 3.Linux中的用户 普通用户与root用户相互转换 普通用户不变root,以root身份执行一个命令 LInux中的角色 4.Linux文件的权限 5.快速掌握修改权限的做法 修改权限 6.对比权限有无表现 对于普通用户&#xf…

五分钟,零基础也能入门 Python 图像文字识别

一. 前言 最近在研究 Python 的一些功能 , 也尝试了一些有趣实现, 这一篇就从实践的角度来研究一下 Python 如何实现图片识别。 众所周知 , Python 的库真的老多了,其中在图像识别上比较突出的就是 OpenCV. 那么基于这个库我们…

基于RAG的大模型知识库搭建

什么是RAG RAG(Retrieval Augmented Generation),即检索增强生成技术。 RAG优势 部分解决了幻觉问题。由于我们可以控制检索内容的可靠性,也算是部分解决了幻觉问题。可以更实时。同理,可以控制输入给大模型上下文内容的时效性&#xff0c…

Day50:WEB攻防-PHP应用文件包含LFIRFI伪协议编码算法无文件利用黑白盒

目录 文件包含-原理&分类&利用&修复 文件读取 文件写入 代码执行 远程利用思路 黑盒利用-VULWEB 白盒利用-CTFSHOW-伪协议玩法 78-php&http协议 79-data&http协议 80-81-日志包含 87-php://filter/write&加密编码 88-data&base64协议 …

17、GateWay和Sentinel继承实现服务限流

注:本篇文章主要参考周阳老师讲解的cloud进行整理的! 1、需求说明 cloudalibaba-sentinel-gateway9528 保护 cloudalibaba-provider-payment9001 2、启动nacos服务器8848 startup.cmd -m standalone 3、启动sentinel服务器8080 java -jar sentinel-dash…

企业微信变更主体公证怎么弄?

企业微信变更主体有什么作用?现在很多公司都用企业微信来加客户,有时候辛辛苦苦积累了很多客户,但是公司却因为各种各样的原因需要注销,那么就需要通过企业微信变更主体的方法,把企业微信绑定的公司更改为最新的。企业…

恶意勒索软件VirLock,通过ApkAnalyser一键提取安卓应用APK敏感信息

恶意勒索软件VirLock,通过ApkAnalyser一键提取安卓应用APK敏感信息。 ############################# 免责声明:本文仅作收藏学习之用,亦希望大家以遵守《网络安全法》相关法律为前提学习,切勿用于非法犯罪活动,对于恶…

python和c语言的区别是什么

Python可以说是目前最火的语言之一了,人工智能的兴起让Python一夜之间变得家喻户晓,Python号称目前最最简单易学的语言,现在有不少高校开始将Python作为大一新生的入门语言。本萌新也刚开始接触Python,发现Python与其他语言确实有…

linux查找指定目录下包含指定字符串文件,包含子目录

linux查找指定目录下包含指定字符串的文件,包含子目录 linux查找指定目录下包含指定字符串的指定文件格式,包含子目录 指定目录 cd /home/www/linux查找指定目录下包含指定字符串的文件,包含子目录 grep -r "指定字符串"注释 gr…