【SpringBoot3.0源码】启动流程源码解析 • 上

news/2024/11/29 11:55:59/

文章目录

  • 初始化

SpringBoot启动类:

@SpringBootApplication
public class AppRun {public static void main(String[] args) {SpringApplication.run(AppRun.class, args);}
}

步入SpringApplication.run(AppRun.class, args)方法:
这里分为两步:

  1. 创建一个SpringApplication实例:初始化一些配置(包括初始化对象和监听器以及一些配置文件)
  2. 调用run方法。
new SpringApplication(primarySources).run(args)

初始化

步入SpringApplication的构造方法中:

首先获取资源加载器、保存primarySources属性、web类型,设置初始化器和监听器,获取main方法所在的类

重点看一下获取初始化器和监听器这部分。

在这里插入图片描述
在此之前,看一下271行的代码:
在SpringBoot的老版本中,是没有这快代码的,这里主要是提前加载一些初始化器、监听器和其他配置放入缓存中,以便后续获取。

this.bootstrapRegistryInitializers = new ArrayList<>(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));

步入getSpringFactoriesInstances方法中:

最终来到这里:这里首先构造一个加载器,再去调用load方法。

在这里插入图片描述
步入forDefaultResourceLocation方法:
最终来到这里:

注意332行代码:如果loaders这个map中有resourceLacation,则返回该key值对应的value。

当然,这里显然是没有的。所以会加载后面的函数,存入loaders中,并返回该值。
在这里插入图片描述
先看看loadFactoriesResource方法做了什么:

首先将项目中含有META-INFO/spring.factories的文件路径加载出来,这里有2个url,一个是autoconfigrition下的,一个是aop下的。

处理完之后去重。

最后收集到18个,包括初始化器和监听器等。

紧接着调用Collections.unmodifiableMap(result)方法。

在这里插入图片描述

看看Collections.unmodifiableMap(result)这个方法:

最后将map存入m这个属性中。

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

分析完SpringFactoriesLoader的参数了,来看看它的构造方法吧:

这样,factories就存入了我们加载出来的类。

在这里插入图片描述

构建完加载器,回去调用这个load方法:

在这里插入图片描述

步入loadFactoryNames方法:

最后会在m这个缓存中取值。

当然这里什么都没有,最后返回null。

在这里插入图片描述

回到最初这里:

在这里插入图片描述
后面两行代码,应该就很清晰了,因为调用的都是同一个getSpringFactoriesInstances方法,因为前者已经加载完配置文件,所以后面这里设置初始化器和监听器会从我们设置好的那个m缓存中获取。

setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

值得注意的是,再次从m这个缓存中获取的时候,我们会取到值,那么这个for循环就会执行:

这里首先会通过反射创建该对象的实例,再add到result的List集合中。

在这里插入图片描述


http://www.ppmy.cn/news/24631.html

相关文章

Vue原理解析

文章目录1. VUE的响应式原理1.1 ViewModel1.2 双向绑定的基本原理1.3 什么是响应性1.4 Vue 中的响应性是如何工作的2. Vue 渲染机制2.1 虚拟 DOM2.2 渲染管线2.3 带编译时信息的虚拟 DOM2.3.1 静态提升2.3.2 修补标记 Flags2.3.3 树结构打平2.3.4 对 SSR 激活的影响1. VUE的响应…

生产Nginx现大量TIME-WAIT,连接耗尽,该如何处理?

背景说明&#xff1a; 在尼恩读者50交流群中&#xff0c;是不是有小伙伴问&#xff1a; 尼恩&#xff0c;生产环境 Nginx 后端服务大量 TIME-WAIT &#xff0c; 该怎么办&#xff1f; 除了Nginx进程之外&#xff0c;还有其他的后端服务如&#xff1a; 尼恩&#xff0c;生产环境…

【图像分类】基于PyTorch搭建LSTM实现MNIST手写数字体识别(双向LSTM,附完整代码和数据集)

写在前面: 首先感谢兄弟们的关注和订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 在https://blog.csdn.net/AugustMe/article/details/128969138文章中,我们使用了基于PyTorch搭建LSTM实现MNIST手…

做 SQL 性能优化真是让人干瞪眼

很多大数据计算都是用SQL实现的&#xff0c;跑得慢时就要去优化SQL&#xff0c;但常常碰到让人干瞪眼的情况。 比如&#xff0c;存储过程中有三条大概形如这样的语句执行得很慢&#xff1a; select a,b,sum(x) from T group by a,b where …; select c,d,max(y) from T grou…

AcWing《蓝桥杯集训·每日一题》—— 3956.截断数组

AcWing《蓝桥杯集训每日一题》—— 3956. 截断数组 文章目录AcWing《蓝桥杯集训每日一题》—— 3956. 截断数组一、题目二、解题思路三、代码实现本次博客我是通过Notion软件写的&#xff0c;转md文件可能不太美观&#xff0c;大家可以去我的博客中查看&#xff1a;北天的 BLOG…

Mysql 存储过程

什么是存储过程&#xff1f; 存储过程是事先经过编译并存储在数据库的一段sql语句的集合 如何创建一个存储过程&#xff1f; create procedure 存储过程名称([参数列表]) beginsql语句; end#例 create procedure p1() beginselect * from t_goods;select * from t_user; end如…

【Android实现16位灰度图数据转RGB数据并以bitmap格式显示】

Android实现16位灰度图数据转RGB数据并以bitmap显示(单通道Gray数据转三通道RGB数据并显示) 需求发现问题解决方案需求 问题需求:项目上需要实现将深度相机传感器给出的数据实时显示出来的功能。经过了解得知,传感器给出的数据为16位灰度图数据,即16位数据表示一个像素的…

SpringMVC基础入门(一)之理论基础概念

文章目录SpringMVC1.概念2.常用注解请求与响应1.请求参数2.JSON传输3.常用注解响应1.响应页面2.响应JSON数据Rest风格1.介绍2.常用注解SpringMVC 1.概念 &#xff08;1&#xff09;定义 SpringMVC是一种基于Java实现MVC模型的轻量级Web框架。 &#xff08;2&#xff09;为什…