SpringBoot源码(三):SpringApplication 对象的初始化

分析下面的代码,底层都做了哪些事情:

new SpringApplication(App.class)
public SpringApplication(Class<?>... primarySources) {this(null, primarySources);
}

初始化SpringApplication

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");// 将我们定义的主启动类 "MyApplication.class" 放到 primarySources 中(这样SpringBoot就知道了主启动类是什么,在哪里)this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));// 1、推断应用环境this.webApplicationType = WebApplicationType.deduceFromClasspath();// 在SpringBoot2.4.0之后引入BootstrapRegistryInitializer(目前没有相关实现类)this.bootstrapRegistryInitializers = new ArrayList<>(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));// 2、设置应用初始化器setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));// 3、设置SpringBoot全局监听器setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 4、确定主启动类this.mainApplicationClass = deduceMainApplicationClass();
}
推断应用环境

this.webApplicationType = WebApplicationType.deduceFromClasspath()

会从当前应用的类路径下,尝试寻找一些特定的类,并以此推断当前应用更适合哪种web环境。(赋值给 SpringApplication 的成员属性:WebApplicationType webApplicationType

public enum WebApplicationType {NONE,SERVLET,REACTIVE;private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet","org.springframework.web.context.ConfigurableWebApplicationContext" };private static final String WEBMVC_INDICATOR_CLASS = "org.springframework.web.servlet.DispatcherServlet";private static final String WEBFLUX_INDICATOR_CLASS = "org.springframework.web.reactive.DispatcherHandler";private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";static WebApplicationType deduceFromClasspath() {// 如果存在 org.springframework.web.reactive.DispatcherHandler && 不存在 org.springframework.web.servlet.DispatcherServlet,则推断为 REACTIVE 环境if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null) && !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {return WebApplicationType.REACTIVE;}// 如果 "javax.servlet.Servlet" 和 "org.springframework.web.context.ConfigurableWebApplicationContext" 当中有任何一个不存在(若返回 SERVLET 环境会不安全),则推断为 NONE 环境for (String className : SERVLET_INDICATOR_CLASSES) {if (!ClassUtils.isPresent(className, null)) {return WebApplicationType.NONE;}}// 返回 SERVLET 环境return WebApplicationType.SERVLET;}
}

当我们引入的是spring-boot-starter-web 依赖,那么SpringBoot启动的就是 Servlet 环境

当我们引入的是spring-boot-starter-webflux 依赖,那么SpringBoot启动的就是 Reactive 环境

如果都没有依赖,那么SpringBoot启动的就是 None 环境(没有web概念)

设置应用初始化器

setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class))

利用Spring的SPI机制,从项目类路径下 META-INF/spring.factories 中加载所有的 ApplicationContextInitializer,反射创建对象 (利用无参构造创建对象)

(赋值给 SpringApplication 的成员属性:List<ApplicationContextInitializer<?>> initializers)

共有下面 7 个 ApplicationContextInitializer 被加载(经过Order 排序后):

org.springframework.boot.context.config.DelegatingApplicationContextInitializer
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer
org.springframework.boot.context.ContextIdApplicationContextInitializer
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
设置应用监听器

setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class))

利用Spring的SPI机制,从项目类路径下 META-INF/spring.factories 中加载所有的 ApplicationListener,反射创建对象

(赋值给 SpringApplication 的成员属性:List<ApplicationListener<?>> listeners)

共有下面 8 个 ApplicationListener 被加载(经过 Order 排序后):

org.springframework.boot.env.EnvironmentPostProcessorApplicationListener
org.springframework.boot.context.config.AnsiOutputApplicationListener
org.springframework.boot.context.logging.LoggingApplicationListener
org.springframework.boot.autoconfigure.BackgroundPreinitializer
org.springframework.boot.context.config.DelegatingApplicationListener
org.springframework.boot.builder.ParentContextCloserApplicationListener
org.springframework.boot.ClearCachesApplicationListener
org.springframework.boot.context.FileEncodingApplicationListener
确定主启动类

this.mainApplicationClass = deduceMainApplicationClass()

推断出主启动类的类对象(即MyApplication的类对象)

(赋值给 SpringApplication 的成员属性:Class<?> mainApplicationClass)

private Class<?> deduceMainApplicationClass() {try {StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();   // stackTrace中保存的就是方法调用栈的信息(使用idea的debug窗口观察函数调用栈看看)for (StackTraceElement stackTraceElement : stackTrace) {// 直到遍历到 main 方法所对应的栈帧if ("main".equals(stackTraceElement.getMethodName())) {// 返回的就是主启动类的类对象 Class@1338 class com.itheima.MyApplication    return Class.forName(stackTraceElement.getClassName());}}}catch (ClassNotFoundException ex) {// Swallow and continue}return null;
}
总结

经过第一步 SpringApplication 构造方法的处理,创建了 SpringApplication 对象, 初始化了它的以下成员属性

private ResourceLoader resourceLoader;
private Set<Class<?>> primarySources;
private WebApplicationType webApplicationType;
private List<BootstrapRegistryInitializer> bootstrapRegistryInitializers;
private List<ApplicationContextInitializer<?>> initializers;
private List<ApplicationListener<?>> listeners;
private Class<?> mainApplicationClass;

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

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

相关文章

LabVIEW离心泵性能优化测试系统

开发了一套基于LabVIEW平台开发的离心泵性能优化测试系统。系统集成了数据采集、流量控制、数据存储、报表生成等功能&#xff0c;提供了低成本、便捷操作的解决方案&#xff0c;适用于工业场景中对离心泵性能的精确测评。 项目背景 随着工业化进程的加速&#xff0c;离心泵在…

论文阅读(三十二):EGNet: Edge Guidance Network for Salient Object Detection

文章目录 1.Introduction2.Related Works3.Salient Edge Guidance Network3.1Complementary information modeling3.1.1Progressive salient object features extraction3.1.2Non-local salient edge features extraction 3.2One-to-one guidance module 4.Experiments4.1Imple…

三大细分领域入选,九州未来再登2024边缘计算产业图谱

10月31日&#xff0c;经过数月的深入调研和专家严格评估&#xff0c;边缘计算社区正式发布《2024边缘计算产业图谱》。该图谱全面收录中国边缘计算领域最具活力的100家企业、科研机构、高校及标准组织等单位&#xff0c;深入梳理产业链上下游发展情况&#xff0c;精准研判边缘计…

【HarmonyOS】鸿蒙系统

文章目录 前言一、鸿蒙OS概述1. 定义与特性2. 核心技术理念3. 技术架构设计1. 应用层2. 框架层3. 系统服务层4. 内核层 二、分布式架构分布式架构的核心理念分布式能力的实现关键技术 三、 总结 前言 鸿蒙OS是由华为推出的一款开源操作系统&#xff0c;旨在满足智能终端设备的…

强网杯 2024 pwn false AK

强网杯 2024 pwn &#x1f3c4;&#x1f3fd;‍♀️前言&#x1f3c4;&#x1f3fd;‍♂️heap&#xff08;UAF house of banana orw&#xff09;&#x1f3c4;&#x1f3fd;分析&#x1f3c4;&#x1f3fd;解题&#x1f3c4;&#x1f3fd;exp &#x1f3c4;&#x1f3fd;‍♂…

w016基于Springboot的房产销售系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

Python毕业设计选题:基于大数据的旅游景区推荐系统_django

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 系统首页界面 用户注册界面 用户登录界面 景点信息界面 景点资讯界面 个人中心界面 …

【c++篇】:掌握vector基础知识--基本操作与使用全知道

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨个人主页&#xff1a;余辉zmh–CSDN博客 ✨文章所属专栏&#xff1a;c篇–CSDN博客 文章目录 前言一.vector的基本概念1.定义2.主要特性和优点 二.vector的基本操作…

基于SSM+微信小程序的订餐管理系统(点餐2)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM微信小程序的订餐管理系统实现了管理员和用户。管理端实现了 首页、个人中心、用户管理、菜品分类管理、菜品信息管理、订单信息管理、配送信息管理、菜品评价管理、订单投诉管理、…

机器学习周报(RNN的梯度消失和LSTM缓解梯度消失公式推导)

文章目录 摘要Abstract 1 RNN的梯度消失问题2 LSTM缓解梯度消失总结 摘要 在深度学习领域&#xff0c;循环神经网络&#xff08;Recurrent Neural Network, RNN&#xff09;被广泛应用于处理序列数据&#xff0c;特别是在自然语言处理、时间序列预测等任务中。然而&#xff0c…

Mastercam2025软件安装教程+MC2025中文安装包下载

一、软件下载 【软件名称】&#xff1a;MasterCAM 2025 【支持系统】&#xff1a;win10/win11 【百度网盘】&#xff1a;https://pan.baidu.com/s/12fY66cwRLGcKdeVoJ40ZRw?pwd70zi 二、Mastercam软件 Mastercam是美国 CNC Software 公司开发的一款 CAD/CAM 软件。它集二维…

[vulnhub] DC: 8

https://www.vulnhub.com/entry/dc-8,367/ 描述&#xff1a;在 Linux 上安装和配置双因素身份验证是否可以防止 Linux 服务器被利用 端口扫描主机发现 探测存活主机&#xff0c;179是靶机 nmap -sP 192.168.75.0/24 Starting Nmap 7.94SVN ( https://nmap.or…

自扶正救生艇,保障水上救援的安全卫士_鼎跃安全

在应急事件中&#xff0c;自扶正救生艇能够发挥关键的救援和保障作用&#xff0c;确保救援人员和被困人员的生命安全&#xff0c;尤其在极端天气或突发水上事故中展现出明显优势。 在救援过程中如果遭遇翻船&#xff0c;救生艇能够迅速恢复正常姿态&#xff0c;确保救援人员不会…

提升网站安全性 HTTPS的重要性与应用指南

内容概要 在如今数字化快速发展的时代&#xff0c;网站安全显得尤为重要。许多用户在访问网站时&#xff0c;尤其是涉及个人信息或金融交易时&#xff0c;对数据传输的安全性有着高度的关注。HTTPS&#xff08;超文本传输安全协议&#xff09;正是为了满足这种需求而诞生的。通…

QT——自定义控件绘图

一.QPaintEvent绘图事件 QPaintEvent是QT中一个重要的类&#xff0c;专门用于绘图事件。当QT视图组件需要重绘制自己的一部分时&#xff0c;就会产生该事件&#xff0c;通常发生在以下几种情况。 窗口第一次显示时&#xff1a;当窗口或控件第一次出现在屏幕中&#xff0c;系统…

【Python · Pytorch】人工神经网络 ANN(上)

【Python Pytorch】人工神经网络 ANN&#xff08;上&#xff09; 0. 生物神经网络1. 人工神经网络定义2. 人工神经网络结构2.1 感知机2.2 多层感知机2.3 全连接神经网络2.4 深度神经网络 2. 训练流程※ 数据预处理 (Data Preprocessing) 3. 常见激活函数3.1 Sigmoid / Logisti…

【Redis_Day2】在Linux中安装Redis5

本篇涉及Linux中的三条指令&#xff1a;su&#xff1b;apt&#xff1b;vim&#xff0c;可以了解后再来浏览本篇。或在评论留言。 【Redis_Day2】在Linux中安装Redis5 安装修改配置文件使用redis-cli连接服务器 安装 Linux版本选择Ubuntu22.04 Redis版本选择Redis5 登录Ubunt…

第1篇 引言

一、AIGC概念 1、AIGC定义 AIGC&#xff0c;即生成式人工智能&#xff08;Artificial Intelligence Generated Content&#xff09;&#xff0c;是指利用人工智能技术自动生成或辅助创作内容的过程和结果。 简单来说&#xff1a;过去&#xff0c;写文章、画张图、唱首歌、弄个…

深度学习---------------------------------Transformer

目录 Transformer架构多头注意力有掩码的多头注意力基于位置的前馈网络层归一化信息传递预测总结代码多头注意力使用多个头并行计算选择缩放点积注意力作为每一个注意力头测试该部分总代码Transformer基于位置的前馈网络改变张量的最里层维度的尺寸对比不同维度的层归一化和批量…

世界时区划分

1. AoE &#xff08;Anywhere on Earth&#xff09;代表地球上最后一个时区的时间&#xff0c;是全球范围内最晚的时间&#xff0c;通常用于截止日期。 2. UTC/GMT &#xff08;协调世界时/格林威治时间&#xff09;是全球的标准时间&#xff0c;所有时区都是基于UTC计算的。…