当前位置: 首页 > news >正文

Spring MVC 启动之 HandlerMapping

        在上一篇文章中,我们介绍了 Spring MVC 的启动流程,接下来我们将发分多个篇章详细介绍流程中的重点步骤

d.png

        今天我们从 HandlerMapping 开始分析,HandlerMapping 是框架中的一个非常重要的组件。它的作用是将URL请求映射到合适的处理程序(Handler)上,这样就能够实现控制器与页面之间的交互。在 Spring MVC 中,有多种不同的 HandlerMapping 实现,本文将对这些实现的作用和源码原理进行详细介绍。

作用

在 Spring MVC 框架中,HandlerMapping 是一个非常重要的组件,它的作用是将URL请求映射到相应的处理程序上。具体来说,HandlerMapping 会根据URL请求的路径、请求参数等信息,确定需要执行哪个处理程序,并将该处理程序返回给 DispatcherServlet。然后 DispatcherServlet 再将请求分配给相应的处理程序,处理程序处理完请求后,将结果返回给 DispatcherServlet,DispatcherServlet 再将结果返回给客户端。

c.png

HandlerMapping的实现

        Spring MVC 框架中有多种不同的 HandlerMapping 实现,每种实现都有不同的作用和使用场景。下面将逐一介绍这些实现。

BeanNameUrlHandlerMapping

        BeanNameUrlHandlerMapping 是 Spring MVC 框架中最简单的 HandlerMapping 实现,它的作用是将 URL 请求的路径映射到 Bean 的名称上。具体来说,当请求的路径与一个 Bean 的名称匹配时,BeanNameUrlHandlerMapping 会将该请求映射到对应的 Bean 上。

例如:

  1. 假设有一个名为 “/hello” 的请求
  2. 我们可以在 Spring 配置文件中定义一个名为 “helloController” 的 Bean
  3. 然后使用 BeanNameUrlHandlerMapping 将 “/hello” 请求映射到该 Bean 上

这样,当客户端发送 “/hello” 请求时,DispatcherServlet 就会将该请求分配给 “helloController” 处理。

BeanNameUrlHandlerMapping 的源码比较简单,它的核心代码如下所示:

public class BeanNameUrlHandlerMapping extends AbstractUrlHandlerMapping {protected Object getHandlerInternal(HttpServletRequest request) throws Exception {String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);return obtainHandler(lookupPath, request);}
}

        从代码中可以看出,BeanNameUrlHandlerMapping 实现了 AbstractUrlHandlerMapping 接口,并重写了其中的 getHandlerInternal 方法。该方法的作用是根据请求的 URL 路径查找相应的处理程序

SimpleUrlHandlerMapping

SimpleUrlHandlerMapping 是 Spring MVC 框架中另一种常用的 HandlerMapping 实现,它的作用是将 URL 请求的路径映射到处理程序上。与 BeanNameUrlHandlerMapping 不同的是,SimpleUrlHandlerMapping 可以将一个URL请求映射到多个处理程序上

例如:

  1. 假设有两个请求 “/hello” 和 “/world”
  2. 我们可以使用 SimpleUrlHandlerMapping 将这两个请求分别映射到不同的处理程序上。具体来说,我们可以在 Spring 配置文件中定义多个 Bean,并分别为它们设置不同的URL路径。
  3. 然后使用 SimpleUrlHandlerMapping 将这些URL路径与相应的处理程序进行映射。

这样,当客户端发送一个请求时,SimpleUrlHandlerMapping 就会根据请求的URL路径查找相应的处理程序,并将请求分配给该处理程序处理。

SimpleUrlHandlerMapping 的源码也比较简单,它的核心代码如下所示:

public class SimpleUrlHandlerMapping extends AbstractDetectingUrlHandlerMapping {protected Object getHandlerInternal(HttpServletRequest request) throws Exception {String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);Object handler = lookupHandler(lookupPath, request);if (handler == null) {handler = getDefaultHandler();}return handler;}
}

        从代码中可以看出,SimpleUrlHandlerMapping 同样实现了 AbstractUrlHandlerMapping 接口(在 AbstractDetectingUrlHandlerMapping 中继承),并重写了其中的 getHandlerInternal 方法。该方法的作用是根据请求的URL路径查找相应的处理程序。

ControllerClassNameHandlerMapping

        ControllerClassNameHandlerMapping 是Spring MVC 框架中一种比较特殊的 HandlerMapping 实现,它的作用是将URL请求的路径映射到 Controller 类名上。具体来说,ControllerClassNameHandlerMapping 会根据请求的URL路径查找对应的 Controller 类名,并将该类返回给 DispatcherServlet,然后 DispatcherServlet 再将请求分配给该 Controller 类处理。

例如:

  1. 假设有一个名为 “/hello” 的请求
  2. 我们可以定义一个名为 HelloController的Controller 类
  3. 使用 ControllerClassNameHandlerMapping 将 “/hello” 请求映射到该类上。

这样,当客户端发送 “/hello” 请求时,ControllerClassNameHandlerMapping 就会将该请求映射到 HelloController 处理。

ControllerClassNameHandlerMapping 的源码也比较简单,它的核心代码如下所示:

public class ControllerClassNameHandlerMapping extends AbstractControllerUrlHandlerMapping {protected Object getHandlerInternal(HttpServletRequest request) throws Exception {String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);String controllerClassName = getClassNameForUrlPath(lookupPath);return obtainApplicationContext().getBean(controllerClassName);}
}

        从代码中可以看出,ControllerClassNameHandlerMapping 同样实现了 AbstractUrlHandlerMapping 接口,并重写了其中的 getHandlerInternal 方法。该方法的作用是根据请求的URL路径查找相应的 Controller 类名,并将该类返回给 DispatcherServlet。

DefaultAnnotationHandlerMapping

        DefaultAnnotationHandlerMapping 是Spring MVC 框架中另一种比较常用的 HandlerMapping实 现,它的作用是将 URL 请求的路径映射到标注了 @RequestMapping 注解的方法上

        具体来说,DefaultAnnotationHandlerMapping 会扫描应用程序中所有标注了 @RequestMapping 注解的方法,并将这些方法与相应的URL路径进行映射。

        然后当客户端发送一个请求时,DefaultAnnotationHandlerMapping 就会根据请求的URL路径查找相应的处理程序,并将该处理程序返回给 DispatcherServlet,然后 DispatcherServlet 再将请求分配给该处理程序处理。

例如:

  1. 假设有一个名为 “/hello” 的请求
  2. 我们可以在 Controller 类的某个方法上标注 @RequestMapping 注解
  3. 将该方法与 “/hello” 请求进行映射。

这样,当客户端发送 “/hello” 请求时,DefaultAnnotationHandlerMapping 就会将该请求映射到该方法上,然后将该方法返回给 DispatcherServlet 处理。

DefaultAnnotationHandlerMapping 的源码比较复杂,因为它需要扫描应用程序中所有标注了 @RequestMapping 注解的方法。其核心代码如下所示:

public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandlerMapping implements BeanFactoryAware, InitializingBean {private final List<RequestMappingInfoHandlerMapping> handlerMappings = new ArrayList<>();protected Object getHandlerInternal(HttpServletRequest request) throws Exception {for (RequestMappingInfoHandlerMapping hm : this.handlerMappings) {HandlerExecutionChain handler = hm.getHandler(request);if (handler != null) {return handler;}}return null;}public void afterPropertiesSet() throws Exception {initHandlerMethods();}protected void initHandlerMethods() {detectHandlerMethods();if (logger.isInfoEnabled()) {logger.info("Mapped " + this.handlerMethods.size() + " request handler methods");}}protected void detectHandlerMethods() {...}
}

        从代码中可以看出,DefaultAnnotationHandlerMapping 同样实现了 AbstractUrlHandlerMapping 接口,并重写了其中的 getHandlerInternal 方法。该方法的作用是根据请求的 URL 路径查找相应的处理程序。

        与其他 HandlerMapping 不同的是,DefaultAnnotationHandlerMapping 还实现了 BeanFactoryAware和InitializingBean 接口,以便在初始化时扫描应用程序中所有标注了 @RequestMapping 注解的方法。

        具体来说,它会调用 detectHandlerMethods 方法,对应用程序中所有标注了 @RequestMapping 注解的方法进行扫描,并将这些方法与相应的URL路径进行映射。

总结

        在 Spring MVC 框架中,HandlerMapping 用于将URL请求的路径映射到相应的处理程序上。框架中提供了多种不同的 HandlerMapping 实现,包括 BeanNameUrlHandlerMapping、SimpleUrlHandlerMapping、ControllerClassNameHandlerMapping 和 DefaultAnnotationHandlerMapping 等。不同的HandlerMapping 实现方式适用于不同的应用场景。

  • BeanNameUrlHandlerMapping 是最简单的HandlerMapping实现,它将 URL 请求的路径直接映射到 Bean 的名称上。
  • SimpleUrlHandlerMapping 则将 URL 请求的路径与相应的处理程序进行映射。
  • ControllerClassNameHandlerMapping 将 URL 请求的路径映射到 Controller 类名上。
  • DefaultAnnotationHandlerMapping 则将 URL 请求的路径映射到标注了 @RequestMapping 注解的方法上。

无论是哪种 HandlerMapping 实现方式,它们都遵循相同的流程来处理请求。具体来说,它们的流程如下:

客户端发送请求到DispatcherServlet。

  1. DispatcherServlet根据请求的URL路径选择相应的HandlerMapping。
  2. HandlerMapping将请求的URL路径与相应的处理程序进行映射。
  3. HandlerMapping返回相应的处理程序。
  4. DispatcherServlet将请求交给相应的处理程序进行处理。
  5. 处理程序进行业务逻辑的处理,并返回相应的结果。
  6. DispatcherServlet将处理程序的结果进行封装,并返回给客户端。

相关文章:

Spring MVC 启动之 HandlerMapping

在上一篇文章中&#xff0c;我们介绍了 Spring MVC 的启动流程&#xff0c;接下来我们将发分多个篇章详细介绍流程中的重点步骤 今天我们从 HandlerMapping 开始分析&#xff0c;HandlerMapping 是框架中的一个非常重要的组件。它的作用是将URL请求映射到合适的处理程序&#x…...

基于YOLOv5的停车位检测系统(清新UI+深度学习+训练数据集)

摘要&#xff1a;基于YOLOv5的停车位检测系统用于露天停车场车位检测&#xff0c;应用深度学习技术检测停车位是否占用&#xff0c;以辅助停车场对车位进行智能化管理。在介绍算法原理的同时&#xff0c;给出Python的实现代码、训练数据集以及PyQt的UI界面。博文提供了完整的Py…...

【Linux系统编程】5.vim基本操作命令

目录 跳转到指定行 命令模式 末行模式 跳转行首 跳转行尾 自动格式化代码 大括号、中括号、小括号对应 光标移至行首 光标移至行尾 删除单个字符 删除一个单词 删除光标至行尾 删除光标至行首 替换单个字符 删除指定区域 删除指定1行 删除指定多行 复制一行 …...

主流机器学习平台调研与对比分析

梗概 本报告主要调研目前主流的机器学习平台&#xff0c;包括但不限于Amazon的Sage maker&#xff0c;Alibaba的PAI&#xff0c;Baidu的PaddlePaddle。对产品的定位、功能、实践、定价四个方面进行详细解析&#xff0c;并通过标杆对比分析提出一套机器学习平台评价体系&#x…...

作业帮基于明道云开展的硬件业务数字化建设

今天由我代表作业帮来介绍公司在低代码平台应用的一些经验和心得。我今天分享的内容包含两部分&#xff0c;一个是作业帮硬件的介绍&#xff0c;另一个是基于明道云的系统能力建设&#xff0c;也是我们自己总结的经验&#xff0c;希望能给大家带来一些启发。 一、关于作业帮 …...

位图及布隆过滤器的模拟实现与面试题

位图 模拟实现 namespace yyq {template<size_t N>class bitset{public:bitset(){_bits.resize(N / 8 1, 0);//_bits.resize((N >> 3) 1, 0);}void set(size_t x)//将某位做标记{size_t i x / 8; //第几个char对象size_t j x % 8; //这个char对象的第几个比特…...

在 Python 中将天数添加到日期

使用 datetime 模块中的 timedelta() 方法将天数添加到日期中&#xff0c;例如 result_1 date_1 timedelta(days3)。 timedelta 方法可以传递天数参数并将指定的天数添加到日期。 from datetime import datetime, date, timedelta# ✅ 将天数添加到日期 my_str 09-24-2023 …...

vue3知识点

一、vue3带来了什么&#xff1f; 1.性能的提升 打包大小减少41% 初次渲染快55%&#xff0c;更新渲染快133% 内存减少54% 2.源码的升级 使用Proxy代替defineProperty实现响应式 重写虚拟DOM的实现和Tree-shaking 3.拥抱TypeScript Vue3可以更好的支持TypeScript 4.新的特性 4.1.…...

一行代码生成Tableau可视化图表

今天给大家介绍一个十分好用的Python模块&#xff0c;用来给数据集做一个初步的探索性数据分析(EDA)&#xff0c;有着类似Tableau的可视化界面&#xff0c;我们通过对于字段的拖拽就可以实现想要的可视化图表&#xff0c;使用起来十分的简单且容易上手&#xff0c;学习成本低&a…...

链表——删除元素或插入元素(头插法及尾插法)

目录 链表的结点由一个结构体构成 判断链表是否为空 键盘输入链表中的数据 输出链表中的数据 返回链表的元素个数 清空链表 返回指定位置的元素值 查找数据所在位置 删除链表的元素 插入元素 建立无头结点的单链表 建立有头结点的单链表&#xff08;头插法&#xff…...

oracle容器的使用

oracle容器的使用 1.下载oracle容器 1.1拉取容器 docker pull registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g拉取国内镜像&#xff0c;该镜像大小为2.99G&#xff0c;已经集成了oracle环境&#xff0c;拉取完可以直接用&#xff0c;推荐使用这款oracle镜像 1.2查看…...

基于springboot会员制医疗预约服务管理信息系统演示【附项目源码】

基于springboot会员制医疗预约服务管理信息系统演示开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea M…...

GoogleAdsense国内加载慢怎么解决?

一淘模板 56admin.com 发现GoogleAdsense&#xff08;谷歌广告联盟&#xff09;国内加载慢拖网站速度怎么解决&#xff1f;GoogleAdsense是谷歌旗下的站长广告联盟系统&#xff0c;如果站长没有好的变现渠道&#xff0c;挂谷歌联盟是最好的选择&#xff08;日积月累&#xff09…...

【MySQL专题】03、性能优化之读写分离(MaxScale)

在我们了解了MySQL的主从复制的性能优化之后&#xff0c;紧接着《【MySQL专题】02、性能优化之主从复制》中&#xff0c;我们提及的读写分离&#xff0c;来进行读操作和写操作分散到不同的服务器结构中&#xff0c;同时希望对多个从服务器能提供负载均衡&#xff0c;读写分离和…...

Redis7高级之BigKey(二)

1.MoreKey案例 往redis里面插入大量测试数据key 生成100W条redis批量设置kv的语句保存在redisTest.txt for((i1;i<100*10000;i)); do echo "set k$i v$i" >> /tmp/redisTest.txt ;done; # 生成100W条redis批量设置kv的语句(keykn,valuevn)写入到/tmp目录下的…...

flex弹性盒子

概念 弹性盒子是一种用于按行或者按列布局的一维布局方法&#xff0c;元素可以膨胀以填充额外的空间&#xff0c;缩小以适应更小的空间 以下属性是给父元素添加的 1.flex-direction --改变轴的方向 row 默认值 默认沿着x轴排版(横向从左到右排列&#xff08;左对齐&#xff…...

[Java Web]Cookie | 一文详细介绍会话跟踪技术中的Cookie

⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;努力输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐所属专栏&#xff1a;Java Web 目录Cookie1、工作原理2、如何使用2.1、发送Cookie2.2、获取Cookie3、Cookie的存活时间4、中文错误Coo…...

这可能是2023最全的Java面试八股文,共计1658页,Java技术手册的天花板

前两天有个小伙伴在后台留言&#xff0c;最近的面试越来越难了&#xff0c;尤其是技术面&#xff0c;考察得越来越细&#xff0c;越来越底层&#xff0c;庆幸的是最终顺利找到了工作。 一般技术面试官都会通过自己的方式去考察程序员的技术功底与基础理论知识 比如果这样的问题…...

字节流及存放本地文件上传和下载文件

前言 之前的文章有写过 vuespringboot使用文件流实现文件下载 实现如何通过 D:\file\文件名.文件格式的形式进行下载文件 但是它对于很多业务场景相对适用性不是很广泛。 以及 elementUI加springboot实现上传excel文件给后端并读取excel 也只能是通过elementui的元素类型进行…...

【翻译】下一步:Go 泛型

原文地址&#xff1a; The Next Step for Generics - The Go Blog https://blog.golang.org/generics-next-step 介绍 自从我们上次写下关于在Go中加入泛型的可能性的文章以来&#xff0c;已经快一年了。现在是该更新的时候了。 设计的更新 我们一直在继续完善泛型设计草案。…...

如何简单实现ELT?

在商业中&#xff0c;数据通常和业务、企业前景以及财务状况相关&#xff0c;有效的数据管理可以帮助决策者快速有效地从大量数据中分析出有价值的信息。数据集成(Data Integration)是整个数据管理流程中非常重要的一环&#xff0c;它是指将来自多个数据源的数据组合在一起&…...

细思极恐,第三方跟踪器正在获取你的数据,如何防范?

细思极恐&#xff0c;第三方跟踪器正在获取你的数据&#xff0c;如何防范&#xff1f; 当下&#xff0c;许多网站都存在一些Web表单&#xff0c;比如登录、注册、评论等操作需要表单。我们都知道&#xff0c;我们在冲浪时在网站上键入的数据会被第三方跟踪器收集。但是&#x…...

Java基础之==,equal的区别(温故而知新)-----点点滴滴的积累

1. 为运算符&#xff0c;equal 为String数据类型的比较方法&#xff1b;相同内容的对象地址不一定相同&#xff0c;但相相同地址的对象内容一定相同&#xff1b; 比较的是值是否相等&#xff0c;equal比较的是是否是同一个对象。 2.基本概念不同 1&#xff09;对于&#xff0c…...

SpringBoot项目使用切面编程实现数据权限管理

springBoot项目使用切面编程实现数据权限管理什么是数据权限管理如何实现数据权限管理什么是数据权限管理 不同用户在某页面看到数据不一致&#xff0c;实现每个用户之间数据隔离的效果。 如以下场景&#xff1a; ● 页面期望展示当前登录人所在部门的数据。 ● 页面期望展示当…...

亚马逊测评是做什么的,风险有哪些?

自养号测评顾名思义就是自己养国外的买家账号给自己店铺提升销量和评论&#xff0c;做过多年的跨境卖家都知道测评可以快速提高产品的排名、权重和销量&#xff0c;&#xff08;国内某宝一样的逻辑&#xff09;但随着测评需求日益增大&#xff0c;卖家在寻求真人测评时也很容易…...

安科瑞导轨式智能通讯管理机

安科瑞 李亚娜 一、概述 AWT200 数据通讯网关应用于各种终端设备的数据采集与数据分析。实现设备的监测、控制、计算&#xff0c;为系统与设备之间建立通讯纽带&#xff0c;实现双向的数据通讯。实时监测并及时发现异常数据&#xff0c;同时自身根据用户规则进行逻辑判断&…...

vs2010下 转换到 COFF 期间失败: 文件无效或损坏

因为同一个电脑上安装多个VS&#xff0c;有多个cvtres.exe。按照下面的操作如果还是不行就在C盘搜索cvtres.exe&#xff0c;然后挨个重命名&#xff0c;看看是调用的哪个&#xff0c;然后修改就可以了。 用VS2010编译C项目时出现这样的错误&#xff1a; LNK1123: 转换到 COFF …...

托福高频真词List19 // 附托福TPO阅读真题

目录 3.28单词 3.29真题​​​​​​​ 3.28单词 legitimately/properlyadv.正当地likewise/similarlyadv.同样地reveal/showv.揭示substantiate/confirmv.证实suppress/stop by forcev.镇压trend/tendencyn.趋势empirical/based on observationa.凭借经验的illuminate/li…...

Go语言项目标准结构应该如何组织的?

这里写自定义目录标题Go项目本身的目录结构Go语言项目典型目录结构GO语言项目最小标准目录结构可执行的Go语言项目目录结构库的Go语言项目目录结构关于internal目录总结参考文章每当我们写一个非hello world实用程序的Go程序或库时&#xff0c;我们都会在项目结构、代码风格和标…...

设计模式简介

设计模式简介 设计模式&#xff08;Design pattern&#xff09;代表了最佳的实践&#xff0c;通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错…...

如何免费建设自己稳定的网站/新闻头条最新消息今天发布

py基础系列&#xff08;三&#xff09;&#xff1a;python容器数据类型&#xff08;下&#xff09;可变类型和不可变类型不可变数据类型可变数据类型不可变数据变量之间的赋值可变数据变量之间的赋值问题不可变类型可以作为键浅复制和深复制浅复制深复制可变类型和不可变类型 …...

做平台网站要增值业务吗/网站发帖推广平台

听了孙鑫老师不到两个小时的讲解。对HTML有了更进一步的了解。之前因为在牛腩前台代码编写的时候接触过这些东西&#xff0c;所以理解起来也不费劲了。下面总结一下这段视频的收获。 主要讲解了HTML元素与标签。如下图所示&#xff1a; 【HTML是什么&#xff1f;】 HTML&#…...

购物网站开发所用技术/百度竞价广告怎么收费

文章目录RDBMS非RDBMSDocumentKey-valueGraphhttps://db-engines.com/en/ranking该网站根据各 DBMS的流行度&#xff0c;列出了它们的排名&#xff0c;每月更新一次。当前是2023年2月份的排名。DataBase Model这一列中显示了各 DBMS所使用的 数据模型&#xff0c;有的使用了单个…...

wordpress优势/如何推广一个产品

报名时间未定 080720 软件工程 [独立本科段] 考试时间2018-04-14上午 09:00-11:3003708 中国近现代史纲要07163 高级数据库技术 //报07167 多媒体计算机技术下午 14:30-17:0003709 马克思主义基本原理概论07169 软件开发工具与环境 //报2018-04-15上午 09:00-11:3002141 计算机…...

龙华网站建设招聘/最近的国际新闻大事

# 该函数有二个作用&#xff1a;# 1、根据给定的二进制运行程序&#xff0c;找出该程序的进程号(PID)。 # 2、判断该二进制程序的运行状态&#xff0c;输出不同的返回値&#xff0c;供查看一个程序的运行状态时使用。 # __proc_pids {program} [pidfile] -----> 该函数的用…...

青岛大学春季高考有网站建设吗/2345导航网址

支持正则表达式...