架构师之路--springboot核心类SpringApplication方法run的源码启动流程

news/2024/12/17 13:55:40/

SpringApplication 类 run 方法源码

    public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();this.configureHeadlessProperty();/**'1:加载所有的 SpringApplicationRunListeners'*/SpringApplicationRunListeners listeners = this.getRunListeners(args);listeners.starting();Collection exceptionReporters;try {/**'2:创建并配置当前应用将要使用的 Environment'*/ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);this.configureIgnoreBeanInfo(environment);/**'3:SpringBoot 的 banner图 output中的图片'*/Banner printedBanner = this.printBanner(environment);/**'4:根据是否是web项目,来创建不同的ApplicationContext容器'*/context = this.createApplicationContext();/**' 新增 '*/exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);/**'6:初始化ApplicationContext'*/this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);/**'7:就是插手容器的启动'*/this.refreshContext(context);/**'8:查找当前context中是否注册有CommandLineRunner和ApplicationRunner,如果有则遍历执行它们。'*/this.afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);}/**'9:执行所有SpringApplicationRunListener的started()方法。'*/listeners.started(context);this.callRunners(context, applicationArguments);} catch (Throwable var10) {this.handleRunFailure(context, var10, exceptionReporters, listeners);throw new IllegalStateException(var10);}

1:通过SpringFactoriesLoader查找并加载所有的 SpringApplicationRunListeners。
通过调用starting()方法通知所有的SpringApplicationRunListeners:应用开始启动了。SpringApplicationRunListeners其本质上就是一个事件发布者,它在SpringBoot应用启动的不同时间点发布不同应用事件类型(ApplicationEvent),如果有哪些事件监听者(ApplicationListener)对这些事件感兴趣,则可以接收并且处理。还记得初始化流程中,SpringApplication加载了一系列ApplicationListener吗?这个启动流程中没有发现有发布事件的代码,其实都已经在SpringApplicationRunListeners这儿实现了。

2: 创建并配置当前应用将要使用的 Environment,Environment用于描述应用程序当前的运行环境,其抽象了两个方面的内容:配置文件(profile)和属性(properties),开发经验丰富的同学对这两个东西一定不会陌生:不同的环境(eg:生产环境、预发布环境)可以使用不同的配置文件,而属性则可以从配置文件、环境变量、命令行参数等来源获取。因此,当Environment准备好后,在整个应用的任何时候,都可以从Environment中获取资源。

  • 判断Environment是否存在,不存在就创建(如果是web项目就创建 StandardServletEnvironment,否则创建
  • StandardEnvironment) 配置Environment:配置profile以及properties
    调用SpringApplicationRunListener的
  • environmentPrepared()方法,通知事件监听者:应用的Environment已经准备好

3:SpringBoot 的 banner图 output中的图片

4:根据是否是web项目,来创建不同的ApplicationContext容器

6:初始化ApplicationContext,主要完成以下工作:

  • 将准备好的Environment设置给ApplicationContext

  • 遍历调用所有的ApplicationContextInitializer的
    initialize()方法来对已经创建好的ApplicationContext进行进一步的处理

  • 调用SpringApplicationRunListener的
    contextPrepared()方法,通知所有的监听者:ApplicationContext已经准备完毕

  • 将所有的bean加载到容器中

  • 调用SpringApplicationRunListener的
    contextLoaded()方法,通知所有的监听者:ApplicationContext已经装载完毕

7:调用ApplicationContext的 refresh()方法,完成IoC容器可用的最后一道工序。就是插手容器的启动

8:查找当前context中是否注册有CommandLineRunner和ApplicationRunner,如果有则遍历执行它们。

9:执行所有SpringApplicationRunListener的started()方法。


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

相关文章

Go项目-----Kubernetes使用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言基本概念kubectl工具部署web服务生成镜像编写deployment 编写service启动服务 k8s部署mysql编写pvc编写pv编写service 部署redis集成部署mysql和redis 前言 这…

超快上手electron,electron保姆级教程(含运行、打包、electron下载慢),利用electron把web端应用转成桌面应用

electron配置步骤 : 1.首先node及npm是否安装。 2.管理者模式cmd进行项目初始化。 mkdir my-test-app cd my-test-app npm init 此时package.json内容如下(有必填项) 3.首管理者模式设置环境变量再安装electron (否则速度太慢)。 $env:ELECTRON_MIRROR"https://npmmirro…

【kafka】简单运用go语言操作kafka实现生产者和消费者功能的包,confluent-kafka-go和sarama

confluent-kafka-go和sarama对比 特性confluent-kafka-gosarama底层实现基于 librdkafka C 库完全用 Go 实现性能高吞吐量、低延迟吞吐量较低&#xff0c;适合常规应用安装依赖需要 C 编译器和 librdkafka无需外部依赖&#xff0c;纯 Go 实现功能支持 Kafka 所有功能&#xff…

旅游资源系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql5.7 4⃣️&#xff1a;技术栈&#xff1a;Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库可…

【C++】11___模板(1)

目录 一、模板的概念 二、函数模板 三、普通函数与函数模板 3.1区别 3.2调用规则 一、模板的概念 模板不能直接使用&#xff0c;它只是一个框架模板的通用并不是万能的分为两类&#xff1a;函数模板、类模板 二、函数模板 函数模板语法&#xff1a; template<typename T…

R环境配置 以及Debug方法 (VSCode, conda, 远程R)

生物信息学中的R环境配置 以及Debug方法 开始设置1、建议使用VSCode conda 远程R2、 VSCode配置安装插件安装好插件后&#xff0c;远程设置链接成功后&#xff0c;设置项目 3、 linux conda 和 远程R配置4、VScode 远程访问R环境下面配置远程R 5、开始Debug新建个R文件&#…

day13 python(1)——python基础

【没有所谓的运气&#x1f36c;&#xff0c;只有绝对的努力✊】 1、python简介 1.1 为什么学习python 1.2 python发展历史 python2.x和python3.x 版本里面有些是不兼容的。&#xff08;我自己本地版本 3.11&#xff09; 2、语言的分类 &#xff08;1&#xff09;编译型 …

MySQL的历史和地位

秋招之后&#xff0c;开始深入学习后端开发知识啦。把学到的东西分享给大家最开心啦。就从MySQL开始吧。 首先说一下MySQL的历史和地位。主要是看一下我们为什么要学习&#xff0c;而不是说让我们学什么我们就学什么。 地位 这张图是我从DB-Engines截取的2024年12月最新的数据…