SpringBoot 源码解析2:启动流程1

SpringBoot 源码解析2:启动流程1

    • 1.启动方式
    • 2.@SpringBootApplication
    • 3.SpringApplication
      • 3.1 构造器SpringApplication
      • 3.2 SpringApplication#run
    • 3.3 SpringApplication#run 中关键方法
      • 3.1 SpringApplication#prepareEnvironment
      • 3.2 SpringApplication#prepareContext
      • 3.3 SpringApplication#createApplicationContext
      • 3.4 SpringApplication#prepareContext
      • 3.5 SpringApplication#refreshContext
      • 3.6 SpringApplicationRunListeners#started
      • 3.7 callRunners
      • 3.8 SpringApplicationRunListeners#running

1.启动方式

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

SpringBoot启动方式,这里就不多做说明了

2.@SpringBootApplication

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {xxxxx
}
  1. 可以看到SpringBootApplication注解由三个注解标注,@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan。
  2. 简要说明一下这三个注解的作用:
    2.1. SpringBootConfiguration由Configuration标注,而Configuration又是由Component标注,Component表明这个类要被Spring管理。同时Configuration注解还能对当前类进行代理。
    2.2. EnableAutoConfiguration是由@Import注解所标注,而Import注解的作用是告诉Spring容器需要注入哪些bean。
    2.3. ComponentScan是用来配置扫描Component资源的策略,包含策略和剔除策略,剔除策略优先及高。

3.SpringApplication

3.1 构造器SpringApplication

@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));this.webApplicationType = WebApplicationType.deduceFromClasspath();setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass = deduceMainApplicationClass();
}
  1. 参数说明:resourceLoader写死null,primarySources为启动类MyApplication。
  2. 通过classLoader判断当前的WebApplicationType,这里返回的是WebApplicationType.SERVLET。
  3. 从spring.factories文件中拿到ApplicationContextInitializer和ApplicationListener。spring.factories文件解析可参考 SpringBoot 基础概念:SpringApplication#getSpringFactoriesInstances
  4. 推断出主类,通过RuntimeException的栈帧信息找到第一个"main"方法所属的类,也就是MyApplication。

3.2 SpringApplication#run

public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();configureHeadlessProperty();SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting();try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);configureIgnoreBeanInfo(environment);Banner printedBanner = printBanner(environment);context = createApplicationContext();exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,new Class[] { ConfigurableApplicationContext.class }, context);prepareContext(context, environment, listeners, applicationArguments, printedBanner);refreshContext(context);afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}listeners.started(context);callRunners(context, applicationArguments);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, listeners);throw new IllegalStateException(ex);}try {listeners.running(context);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, null);throw new IllegalStateException(ex);}return context;
}
  1. 这是SpringBoot真正启动的总流程。
  2. 从spring.factories文件中获取SpringApplicationRunListener对应的类,通过参数类型为SpringApplication.class, String[].class的构造器实例化,其中值为当前的SpringApplication对象和启动参数args,封装在SpringApplicationRunListeners里。其实是实例化了EventPublishingRunListener,从名字上可知,它是用来分发事件的。
    在这里插入图片描述
  3. 调用SpringApplicationRunListeners#starting发布"正在启动"事件,事件为ApplicationStartingEvent。
  4. prepareEnvironment方法发布"环境准备"事件,由ConfigFileApplicationListener监听,然后解析配置文件(如yml、bootstrap、properties、xml等),将解析的信息存放到Environment里面。
  5. printBanner方法打印banner
  6. createApplicationContext创建ApplicationContext,判断的依据是webApplicationType。由于是Servlet类型的,创建的是AnnotationConfigServletWebServerApplicationContext。
  7. 获取异常报告事件监听器,在catch到异常监听failed。
  8. 准备applicationContext
  9. refreshContext(context)刷新容器
  10. listeners.started(context) 发布"已启动"事件
  11. 调用ApplicationRunner和CommandLineRunner
  12. listeners.running发送"running事件"

3.3 SpringApplication#run 中关键方法

3.1 SpringApplication#prepareEnvironment

3.2 SpringApplication#prepareContext

3.3 SpringApplication#createApplicationContext

3.4 SpringApplication#prepareContext

3.5 SpringApplication#refreshContext

3.6 SpringApplicationRunListeners#started

3.7 callRunners

3.8 SpringApplicationRunListeners#running

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

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

相关文章

BIM 技术:角色漫游

本心、输入输出、结果 文章目录 BIM 技术&#xff1a;角色漫游前言BIM角色漫游中&#xff0c;用户如何与建筑模型进行交互手势识别技术在BIM角色漫游中的应用有哪些图示花有重开日&#xff0c;人无再少年实践是检验真理的唯一标准 BIM 技术&#xff1a;角色漫游 编辑&#xff1…

基于ssm金旗帜文化培训学校网站的设计与开发论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对培训学校展示信息管理混乱&#xff0c;出错率高&#xff0c;信息安全…

【云原生kubernets】Pod详解

一、Pod介绍 1.1.概念 Pod是kubernetes中最小的资源管理组件&#xff0c;Pod也是最小化运行容器化应用的资源对象。一个Pod代表着集群中运行的一个进程。kubernetes中其他大多数组件都是围绕着Pod来进行支撑和扩展Pod功能的&#xff0c;例如&#xff0c;用于管理Pod运行的State…

使用国内镜像源安装opencv

在控制台输入命令&#xff1a; pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple 验证安装&#xff1a; step 1&#xff1a; 打开终端&#xff1b;step 2&#xff1a; 输入python&#xff0c;进入Python编译环境&#xff1b;step 3&#xff1a; 粘贴…

打开软木塞,我们来谈谈葡萄酒泡泡吧

香槟是任何庆祝场合的最佳搭配。从婚礼和生日到单身派对和典型的周五晚上&#xff0c;这款气泡饮料是生活中特别聚会的受欢迎伴侣。 来自云仓酒庄品牌雷盛红酒分享你知道吗&#xff0c;你喜欢喝的那瓶香槟酒可能根本不是香槟&#xff0c;而是汽酒&#xff1f;你不是唯一一个认…

面试官:你对SPA单页面的理解,它的优缺点分别是什么?如何实现SPA应用呢

一、什么是SPA SPA&#xff08;single-page application&#xff09;&#xff0c;翻译过来就是单页应用SPA是一种网络应用程序或网站的模型&#xff0c;它通过动态重写当前页面来与用户交互&#xff0c;这种方法避免了页面之间切换打断用户体验在单页应用中&#xff0c;所有必要…

系统安全-应用威胁风险检查项及预防方案

系统安全-应用威胁风险检查项及预防方案 1、欺骗&#xff08;认证&#xff09; 2、篡改&#xff08;授权和加密&#xff09; 3、抵赖&#xff08;日志记录和数字签名&#xff09; 4、信息泄露&#xff08;敏感信息保护&#xff09; 5、特权提升 6、拒绝服务&#xff08;数据稀释…

ubuntu安装详细步骤

一&#xff0c;先下载vmware 1&#xff0c;第一步打开上面链接 下载网址 : https://www.vmware.com/products/workstation-pro/wo rkstation-pro-evaluation.html 许可证 JU090-6039P-08409-8J0QH-2YR7F ZF3R0-FHED2-M80TY-8QYGC-NPKYF FC7D0-D1YDL-M8DXZ-CYPZE-P2AY6 ZC3T…

【SpringBoot篇】Interceptor拦截器 | 拦截器和过滤器的区别

文章目录 &#x1f339;概念⭐作用 &#x1f384;快速入门⭐入门案例代码实现 &#x1f6f8;拦截路径&#x1f354;拦截器interceptor和过滤器filter的区别&#x1f386;登录校验 &#x1f339;概念 拦截器&#xff08;Interceptor&#xff09;是一种软件设计模式&#xff0c;…

蓝桥杯专题-真题版含答案-【祖冲之割圆法】【错误票据】【显示为树形】【汉字相乘】

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

【自定义Source、Sink】Flink自定义Source、Sink对ClickHouse进行读和批量写操作

ClickHouse官网文档 Flink 读取 ClickHouse 数据两种驱动 ClickHouse 官方提供Clickhouse JDBC.【建议使用】第3方提供的Clickhouse JDBC. ru.yandex.clickhouse.ClickHouseDriver ru.yandex.clickhouse.ClickHouseDriver.现在是没有维护 ClickHouse 官方提供Clickhouse JDBC…

华为ensp-无线小型wlan配置教程

实验拓扑图&#xff1a; 实验平台&#xff1a;ENSP510 实验设备&#xff1a;Centered Cloud、AC6005、AP4030、STA、Cellphone vlan范围划分 vlan 101 : 10.23.101.1/24 vlan 100 : 10.23.100.1/24实验步骤&#xff1a; 一、创建VLAN100、101配置端口类型 [AC1]vlan batch 100…

STM32启动流程详解(超全,startup_stm32xx.s分析)

单片机上电后执行的第一段代码 1.初始化堆栈指针 SP_initial_sp 2.初始化 PC 指针Reset_Handler 3.初始化中断向量表 4.配置系统时钟 5.调用 C 库函数_main 初始化用户堆栈&#xff0c;然后进入 main 函数。 在正式讲解之前&#xff0c;我们需要了解STM32的启动模式。 STM32的…

【Vue】日期格式化(全局)

系列文章 【Vue】vue增加导航标签 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/134965353 【Vue】Element开发笔记 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/133947977 【Vue】vue&#xff0c;在Windows IIS平台…

关于“Python”的核心知识点整理大全23

目录 ​编辑 第&#xff11;0 章 文件和异常 10.1 从文件中读取数据 10.1.1 读取整个文件 pi_digits.txt file_reader.py 10.1.2 文件路径 10.1.3 逐行读取 file_reader.py 10.1.4 创建一个包含文件各行内容的列表 10.1.5 使用文件的内容 pi_string.py 往期快速传…

Microsoft visual studio 2013卸载方法

1、问 题 Microsoft visual studio 2013 无法通过【程序与功能】卸载 2、解决方法 使用微软的Microsoft visual studio 2013 专用卸载工具 工具下载链接&#xff1a;https://github.com/Microsoft/VisualStudioUninstaller/releases 或 链接&#xff1a;https://pan.baidu.c…

【自动化测试】web3py 连接 goerli

web3py 连接 goerli 直接使用库里方法 if __name__ __main__:from web3.auto.infura.goerli import w3w3.eth.get_balance(get_address_by_private_key(os.getenv("AAA_KEY")))error info: websockets.exceptions.InvalidStatusCode: server rejected WebSocket …

02-MQ入门之RabbitMQ简单概念说明

二&#xff1a;RabbitMQ 介绍 1.RabbitMQ的概念 RabbitMQ 是一个消息中间件&#xff1a;它接受并转发消息。你可以把它当做一个快递站点&#xff0c;当你要发送一个包裹时&#xff0c;你把你的包裹放到快递站&#xff0c;快递员最终会把你的快递送到收件人那里&#xff0c;按…

LeetCode 1143最长公共子序列 1035不相交的线 53最大子序和 | 代码随想录25期训练营day53

动态规划算法11 LeetCode 1143 最长公共子序列 2023.12.16 题目链接代码随想录讲解[链接] int longestCommonSubsequence(string text1, string text2) {//1确定dp二维数组&#xff0c;dp[i][j]表示以text1[i-1]、text2[j-1]结尾相同的公共子序列的最大长度vector<vecto…

普通二叉树和右倾斜二叉树--LeetCode 111题《Minimum Depth of Binary Tree》

本文将以解释计算二叉树的最小深度的思路为例&#xff0c;致力于用简洁易懂的语言详细描述普通二叉树和右倾斜二叉树在计算最小深度时的区别。通过跟随作者了解右倾斜二叉树的概念以及其最小深度计算过程&#xff0c;读者也将对左倾斜二叉树有更深入的了解。这将为解决LeetCode…