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…

SOLIDWORKS 2025用户体验新功能

SOLIDWORKS 2025用户体验新功能 北京众联亿诚是达索官方授权的SOLIDWORKS经销商&#xff0c;专业经销SOLIDWORKS正版软件并提供免费试用、培训认证、二次开发等增值服务。 在快速迭代的制造业环境中&#xff0c;电气设计作为产品开发的重要组成部分&#xff0c;其效率和准确性…

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

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

指向指针的指针+ 值传递的理解

//17、下面的程序会出现什么结果 #include #include void getmemory(char *p) { p(char *) malloc(100); strcpy(p,”hello world”); } int main( ) { char *strNULL; getmemory(str); printf(“%s/n”,str); free(str); return 0; } // 程序崩溃&#xff0c…

持续改进之路:运维中的常见挑战及解决方案

在运维工作中,团队经常会遇到各种各样的挑战。这些挑战不仅影响系统的稳定性和性能,还可能导致服务中断,影响用户体验。本文将通过具体案例,详细解析运维中常见的挑战,并提供相应的解决方案,帮助读者更好地理解和应对这些问题。 案例一:服务器过载导致服务中断 问题描…

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

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

windows C#-对象

类或结构定义的作用类似于蓝图&#xff0c;指定该类型可以进行哪些操作。 从本质上说&#xff0c;对象是按照此蓝图分配和配置的内存块。 程序可以创建同一个类的多个对象。 对象也称为实例&#xff0c;可以存储在命名变量中&#xff0c;也可以存储在数组或集合中。 使用这些变…

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

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

基于Opencv的图像处理软件

本文所涉及所有资源均在 传知代码平台 可获取。 目录 一、背景及意义介绍 背景 意义

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

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

equal和==的比较

equal是一个方法&#xff0c;用于比较两个对象的值是否相等。 是一个运算符&#xff0c;用于比较两个对象的引用是否相等。 在Java中&#xff0c;对于基本数据类型&#xff0c;用于比较它们的值是否相等。而对于引用类型&#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…

【Rust标准库中的convert(AsRef,From,Into,TryFrom,TryInto)】

Rust标准库中的convert&#xff08;AsRef&#xff0c;From&#xff0c;Into&#xff0c;TryFrom&#xff0c;TryInto&#xff09; 为什么需要convert库AsRef&#xff08;不可变引用&#xff1a;多用于内部字段获取值&#xff09;From/Into Trait | TryFrom/TryInto TraitFrom T…

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

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