SpringMVC 笔记篇

1.1 执行流程

1.1.5 DispatcherServlet的init()——> 创建Spring容器 ——>  initStrategies()方法

在1.1.4中DispatcherServlet中的init()方法创建Spring容器之外,其实还会做一件特别重要的事,在FrameworkServlet中的refresh()方法执行之前,去添加一个监听器(ApplicationListener)。

我们在ContextRefreshListener上跟进一下代码

(ContextRefreshedEvent),这个事件是Spring容器扫描完之后,把一些单例Bean都创建完成之后,就会发布这样一个事件,表示Spring容器刷新完成的一个事件,一旦容器创建好了,此时onApplicationEvent方法就会执行,从而就会来执行方法体中的onApplicationEvent,跟进之后

从而就会执行onRefresh方法,具体的其实是执行的具体的实现,因为FrameworkServlet是父类,真正的实现是我们的DispatcherServlet类中的onRefresh方法。

相当于最终会执行到DispatcherServlet类中的onRefresh方法中的initStrategies()方法中。

其实就是SpringMVC创建完Spring容器之后,会发布一个事件,而我们有一个Listener会接收这个事件,并且最终会调用initStrategies()方法。

我们要理解的一件事就是DispatcherServlet的初始化,除了会去创建Spring容器,而且还会去创建一些其他的,也就是initStrategies()方法中的一些其他的方法(DispatcherServlet的init()——> 创建Spring容器 ——>  initStrategies()方法),这些其他的方法都是为了方便我们后续处理请求。

我们现在来看一下这个initStrategies()方法 ,鼠标跟进之后可以看到如下代码。

 我们看一下其中的initHandlerMapping()方法。

跟进之后可以看到

 首先会默认判断一下detectAllHandlerMappings属性,这个属性默认为true,当它为true的时候就会执行下面的方法,会根据HandlerMapping.class去Spring容器中读取Bean。因为根据类型去拿Bean,可能会拿到多个,所以用Map集合,并且会判断一下是否为空并且进行排序。

当然,下面还有一些detectAllHandlerMappings为false的情况

以及没有配置的情况,如果从Spring容器中没有拿到(根据HandlerMapping.class去Spring容器中读取Bean失败),它会有一个默认的选择,也就是下面的getDefaultStrategies()方法。

我们可以跟进一下getDefaultStrategies()方法,可以看到DEFAULT_STRATEGIES_PATH

 跟进一下DEFAULT_STRATEGIES_PATH可以看到默认去拿DispatcherServlet.properties这个文件。(这个文件SpringMVC中默认会写这个文件,当然我们也可以自己去写)

 DispatcherServlet.properties文件内容:

在拿到DispatcherServlet.properties文件中的HandlerMapping之后,我们可以打个断点,看一下拿到的key是什么,由于我们没有配置,所以拿到的是默认的,也就是DispatcherServlet.properties文件中的HandlerMapping中的默认的那三个。

 拿到这三个之后就会去遍历,拿到具体的类(根据名字进行类加载),然后去调用createDefaultStrategy()方法。

跟进一下createDefaultStrategy()方法 ,它会利用BeanFactory和Spring容器去针对这个clazz类型去创建一个Bean对象。

DispatcherServlet的init()——> 创建Spring容器 ——>  initStrategies()方法 ——> RequestMappingHandlerMapping Bean对象 ——> 执行afterPropertiesSet()方法

afterPropertiesSet()方法是RequestMappingHandlerMapping中的方法。 

在afterPropertiesSet()方法中 

它会调用super.afterPropertiesSet()方法,跟进一下这个方法,可以看到initHandlerMethods()方法

 跟进一下initHandlerMethods()方法

通过for循环拿到所有的Bean ,然后调用processCandidateBean()方法,我们跟进这个方法来看一下

首先会拿到我们所有的Bean类型(beanType)

 然后会去判断Bean类型(beanType),跟进一下isHandler()方法

然后 点击左侧的绿色箭头,找到真正的实现类

 拿到一个beanType之后(比如传进来的是一个XXXController),首先会判断当前这个类上面有没有Controller注解或者有没有RequestMapping注解,只要符合其中一个条件就表明这是一个Handler。

说白了就是DispatcherServlet的init()——> 创建Spring容器 ——>  initStrategies()方法 ——> RequestMappingHandlerMapping Bean对象 .afterPropertiesSet()方法 ——>有哪些Controller

所以我的Controller可以这样写,test()方法也是可以执行的。

import org. springframework. web. bind. annotation. GetMapping;
import org. springframework. web. bind. annotation. RequestMapping;
import org. springframework. web. bind. annotation. ResponseBody;@Component
@RequestMapping
public class XXXController {@GetMapping("/a")@ResponseBodypublic String test() {return " kanglingfeng success";}
}

或者这样写,都是可以的。

import org. springframework. stereotype.Controller;
import org. springframework. web. bind. annotation. GetMapping;
import org. springframework. web. bind. annotation. ResponseBody;@Controller
public class XXXController {@GetMapping("/a")@ResponseBodypublic String test() {return " kanglingfeng success";}
}

当确定了这个类是一个Controller,会去找这个类里面所有的方法。

我们可以跟进一下getMappingForMethod()方法 

点击左侧的绿色箭头找到具体的实现

 点进去之后

找到createRequestMappingInfo()方法,跟进之后

 可以看到findMergedAnnotation()方法,这一套流程就是为了判断当前这个类中的某个方法上面是不是有RequestMapping注解,并且把注解相关的一些信息解析出来,最终就可以得到对应的一个RequestMappingInfo。

import org. springframework. web. bind. annotation. RequestMapping;
import org. springframework. web. bind. annotation. ResponseBody;@Component
@RequestMapping
public class XXXController {@RequestMapping(value = "/a",method = POST)@ResponseBodypublic String test() {return " kanglingfeng success";}
}

相当于我们现在的这个逻辑就是找到了这个Controller之后,它就会找里面的方法,然后找里面加了RequestMapping注解的方法,并且解析这个注解里面你所设置的内容,然后把这些内容封装成为一个RequestMappingInfo对象。

找到了所有的Controller方法之后,遍历所有的方法,再把这些方法注册到mappingRegistery里面,为了后续更方便去寻找。(当我接收到某个请求之后,我就可以很快速的根据真正请求的URL,去找到对应的方法)

跟进一下registerHandlerMethod()方法

 DispatcherServlet的init()——> 创建Spring容器 ——>  initStrategies()方法 ——> RequestMappingHandlerMapping Bean对象 .afterPropertiesSet()方法 ——> mappingRegistry(请求URL:Method)

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

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

相关文章

景联文科技提供运动数据采集服务

运动数据的重要性 运动数据的收集与分析对于提升个人健康管理和运动表现具有重要意义。 通过收集心率、步态、速度等生理和运动参数,不仅可以为运动员提供个性化的训练方案,帮助其优化表现,还能早期发现并预防伤病。对于普通健身者而言&…

CSS溢出——WEB开发系列20

在网页设计中,“溢出”是一个常见且重要的概念。它涉及到如何处理那些超出预定范围的内容,以确保网页的布局和视觉效果达到预期。 一、什么是溢出? 在 CSS 中,“溢出”(overflow)指的是内容超出其包含块的…

python-pptx - Python 操作 PPT 幻灯片

文章目录 一、关于 python-pptx设计哲学功能支持 二、安装三、入门1、你好世界!例子2、Bullet 幻灯片示例3、add_textbox()示例4、add_picture()示例5、add_shape()示例6、add_table()示例7、从演示文稿中的幻灯片中提取所有文本 四、使用演示文稿1、打开演示文稿2、…

Marscode:程序员的智能伙伴,2024 活动震撼来袭

在程序员的世界里,高效的开发工具如同手中的利器,能让我们在代码的海洋中披荆斩棘。今天,我要向大家隆重介绍一款强大的智能开发工具——Marscode,以及它带来的精彩 2024 活动。 一、Marscode:智能开发的新势力 Mars…

SQLite的安装和使用

一、官网链接下载安装包 点击跳转 步骤:点击安装这个红框的dll以及红框下面的tools (如果有navicat可以免上面这个安装步骤,安装上面这个是为了能在命令行敲SQL而已) 二、SQLite的特点 嵌入的(无服务器的&#x…

【机器学习】 7. 梯度下降法,随机梯度下降法SGD,Mini-batch SGD

梯度下降法,随机梯度下降法SGD,Mini-batch SGD 梯度下降法凸函数(convex)和非凸函数梯度更新方向选择步长的选择 随机梯度下降SGD(Stochastic Gradient Descent)梯度下降法:SGD: Mini-batch SGD 梯度下降法 从一个随机点开始决定下降方向(重要&#xff…

基于PHP+MySQL组合开发的微信投票小程序 带完整的安装代码包以及搭建教程

系统概述 这款基于 PHPMySQL 组合开发的微信投票小程序是一款专门为满足各类投票需求而设计的应用程序。它利用 PHP 强大的服务器端编程能力和 MySQL 高效的数据存储和管理能力,为用户提供了一个稳定、可靠、功能丰富的投票平台。 该小程序支持多种投票类型&#…

centos安装docker并配置加速器

docker安装与卸载: 1、检查当前是否安装docker yum list installed | grep docker2、卸载docker 根据yum list installed | grep docker查询出来的内容,逐个进行删除 yum remove docker.x86 64 -y3、启动与关闭docker 4、删除/etc/docker文件夹 如果…

jmeter 响应乱码

Jmeter在做接口测试的时候的,如果接口响应的内容中有中文,jmeter的响应内容很可能显示乱码,为了规避这种出现乱码的问题,就要对jmeter的响应结果进行编码处理。 打开jmeter进行接口、压力、性能等测试,出现以下乱码问…

Java短剧系统新生态智能系统打造个性化影视体验小程序源码

短剧新生态,智能系统打造个性化影视体验✨🎬 🎉 开篇:短剧新纪元,个性化体验来袭 在这个快节奏的时代,短剧以其精炼的剧情和高效的传播力,正逐渐成为影视娱乐的新宠儿!&#x1f38…

如何恢复删除的微信好友?不留遗憾,这5招教你找回

在社交生活中,微信成为了我们日常沟通的重要工具之一。然而,偶尔因一时冲动或误操作删除了重要好友,当我们想找回好友时是否也在懊悔呢?如何恢复删除的微信好友就成为了我们必须学会的技能。那么,今天我们就来分享5种高…

10、ollama启动LLama_Factory微调大模型(llama.cpp)

在前面章节中介绍了如何使用LLama_Factory微调大模型,并将微调后的模型文件合并导出,本节我们我们看下如何使用ollama进行调用。 1、llama.cpp LLama_Factory训练好的模型,ollama不能直接使用,需要转换一下格式,我们…

STM32G474之TIM1更新中断

STM32G474之TIM1能产生如下的中断: 1、捕获比较1个事件(Capture compare 1 event) 用来获取“捕获输入脉冲的时间”,其次用来输出“比较输出波形”; 2、捕获比较2个事件(Capture compare 2 event&#x…

【HTML源码】上传即可使用的在线叫号系统源码

这个叫号系统的过程是这样的 接了一个任务,某学校要对学生进行逐个面试,希望能有类似医院门诊那种叫号系统。 条件:首先说硬件,就是教室里边一台笔记本电脑,同屏到教室外面的电视机。 需求:软件需求是可…

如何解决U盘无法压缩卷或删除卷的问题

U盘在日常使用中,偶尔会遇到无法压缩卷或删除卷的情况。出现这些问题通常与U盘的磁盘状态或文件系统有关。本文将介绍一种有效的解决方法,通过使用Windows自带的磁盘管理工具diskpart来解决这些问题。 一、问题原因 U盘无法压缩卷或删除卷的常见原因包…

扩博智能× Milvus:图像检索助力零售商品图像高效标注

大家好,我是上海扩博智能技术有限公司的Frank,负责算法工程相关的工作。很高兴能在 Milvus 社区和大家分享我们在图像检索方面的经验。 01 扩博智能公司简介 扩博智能 Clobotics 成立于 2016 年,总部位于上海长宁。我们聚焦计算机视觉和机器学…

el-table 合并单元格后 hover错乱

hover后的效果图: 1:在el-table上加入这三个属性 :row-class-name"rowClassName" cell-mouse-enter"handleMouseEnter" cell-mouse-leave"handleMouseLeave" 2:data里声明一个变量 hoverRowLike:-1 3:copy到…

自动化测试:Monkey工具实践应用~

在移动应用的自动化测试中,意外的用户操作和各种不可预见的场景往往是导致应用崩溃的主要原因。如何有效地模拟这些复杂场景,成为了测试工程师的一大挑战。而在这一过程中,Monkey工具凭借其随机化测试的独特优势,成为了许多团队的…

29 猜丁壳游戏

猜丁壳游戏 猜丁壳游戏是一个简单的石头、剪刀、布游戏,玩家与计算机进行对战。以下是游戏的详细说明和使用指南。 游戏界面 游戏界面分为几个部分: 标题栏:显示游戏名称“猜丁壳”。选择区域:玩家可以选择石头、剪刀或布。控制…

Python简易IDE工作界面制作

、 休闲一下,学习编程还是要学习一些界面编程,能够根据需要制作图形操作界面,这样我们开发的程序才能方便操作和使用,同时获得更友好的人机交互体验。下面是一个用PyQt5制作的简易界面,供大学参考。如下图所示&a…