SpringBoot:SpringBoot启动过程原理 ---- 25

ssssSpringBoot框架的原理是很复杂的,但又是简单的,因为他不是最底层的框架,而是由不同的框架组成的,主要分为以下几个部分:

ssss①. Spring原理【Spring注解】、ssss②. SpringMVC原理ssss③. 自动配置原理. ssss④. SpringBoot(启动)原理

ssss⑤. 第三方框架 …

      • SpringBoot启动过程
        • ● 创建 SpringApplication
        • ● 运行 SpringApplication----->Run()方法
      • SpringBoot启动过程

SpringBoot启动过程

ssss我们以 “deBug” 方式来进行分析:
sdsdsdsadsddsdsasdassSpringBoot:SpringBoot启动过程原理 ---- 25_第1张图片
sdsddsdsdsssSpringBoot:SpringBoot启动过程原理 ---- 25_第2张图片
ssss【注】:我们发现SpringBoot启动主要由两部分组成:①、● 创建 SpringApplication ②、● 运行 SpringApplication,接下来我们分别分析这两个方法

● 创建 SpringApplication

asdasdssSpringBoot:SpringBoot启动过程原理 ---- 25_第3张图片
ssss ①、 保存一些信息。eg: 自定义环境、加载器等。

ssss ②、通过断言机制,如果当前传入的类为空,则直接终端运行,并回复"PrimarySources must not be null"

ssss ③、将传入类的相关信息存储起来,数据结构是 “LinkedHashSet”
sdasdasdsdasdss在这里插入图片描述
ssss ④、 判定当前应用的类型。使用的工具式:ClassUtils,最终返回Servlet
ssdsdsddsddsdssSpringBoot:SpringBoot启动过程原理 ---- 25_第4张图片
ssss ⑤、去spring.factoriesApplicationContextInitializer初始化器ApplicationListener监听器。
SpringBoot:SpringBoot启动过程原理 ---- 25_第5张图片
ssss【注1】:我们将找到的监听器等分别存储到了ArrayList中,并且spring.factories指的是导入的所有包中的spring.factories,比如下面是其中的一个包中spring.factories
SpringBoot:SpringBoot启动过程原理 ---- 25_第6张图片
ssss【注2】:在之前版本的SpringBoot,还会寻找 bootstrappers:初始启动引导器(List< Bootstrapper >):去spring.factories文件中找org.springframework.boot.Bootstrapper,但是在2.5版本没有。

ssss ⑥、在堆栈中找“main()”方法然后存储起来,比如当前的main方法: class com.atguigu.webadmin.Boot05WebAdminApplication .
ssdsdsddsdsdsdsdsdsdsdsdss在这里插入图片描述

● 运行 SpringApplication----->Run()方法

ssasdassSpringBoot:SpringBoot启动过程原理 ---- 25_第7张图片
ssss● 运行 SpringApplication,即run()方法:

sssdsadas ①. StopWatchsss【注】:创建一个StopWach实例,为了后续记录时间

sssdsadas ②. 记录应用的启动时间 stopWatch.start();

sssdsadas【注】:在早写的SpringBoot版本,在这之后还创建引导上下文(Context环境)createBootstrapContext(),获取所有之前的 bootstrappers 挨个执行 intitialize() 来完成对引导启动器上下文环境设置。

sssdsadas ③. 让当前应用进入headless模式。java.awt.headless

sssdsadas【注】:headless模式是缺少显示设备,键盘或鼠标的系统配置。 听起来很意外,但实际上您可以在此模式下执行不同的操作,即使使用图形数据也是可以的。
sssdsadas ④. 获取所有 RunListener(运行监听器)【为了方便所有Listener进行事件感知】,然后遍历它们执行 starting() 方法:
sssdsadas【注】:getSpringFactoriesInstances 去spring.factories找 SpringApplicationRunListener.
sssdsadas【注】: starting():相当于通知所有感兴趣系统正在启动过程的人,项目正在 starting。

sssdsadas ⑤. 保存命令行参数;ApplicationArguments

sssdsadas ⑥. 准备环境 prepareEnvironment();
ssdsdssdsSpringBoot:SpringBoot启动过程原理 ---- 25_第8张图片
sssdsadsaddas ■ 返回或者创建基础环境信息对象,返回是StandardServletEnvironment
sssdsadsaddas ■ 配置环境信息对象。
sssdsadsdsdsaddas ● 读取所有的配置源的配置属性值。
sssdsadsaddas ■ 监听器调用 listener.environmentPrepared();通知所有的监听器当前环境准备完成
sssdsadsaddas ■ 绑定环境信息
sssdsadas【注】:在这之后还会配置一些忽略的信息,并且通过banner显示图标.
ssdsdsdsdsdsdsdsddssddssdssdsSpringBoot:SpringBoot启动过程原理 ---- 25_第9张图片
sssdsadas ⑦. 创建IOC容器(createApplicationContext())
sssdsadsaddas ■ 根据项目类型(Servlet)创建容器,
sssdsadsaddas ■ 当前会创建 AnnotationConfigServletWebServerApplicationContext
SpringBoot:SpringBoot启动过程原理 ---- 25_第10张图片
sssdsadas【注】:在这之后会获得异常报告。

sssdsadas ⑧. 准备ApplicationContext IOC容器的基本信息 prepareContext()
ssdsddssdsadsdSpringBoot:SpringBoot启动过程原理 ---- 25_第11张图片
sssdsadsaddas ■ 保存环境信息
sssdsadsaddas ■ IOC容器的后置处理流程。
sssdsadsaddas ■ 应用初始化器;applyInitializers;
sssdsadsdsdsaddas ● 遍历所有的 ApplicationContextInitializer 。调用 initialize.。来对IOC容器进行初始化扩展功能
sssdsddsdsadSpringBoot:SpringBoot启动过程原理 ---- 25_第12张图片
sssdsadsdsdsaddas ● 遍历所有的 listener 调用 contextPrepared。EventPublishRunListenr;通知所有的监听器contextPrepared
sssdsdsddsdssddsdsadSpringBoot:SpringBoot启动过程原理 ---- 25_第13张图片
sssdsadsaddas ■ 所有的监听器 调用 contextLoaded。通知所有的监听器 contextLoaded;

sssdsadas⑨. 刷新IOC容器。refreshContext。容器刷新完成后再进行相关工作afterRefresh,不过看源码什么也没有,应该是给人们写的。
sdsdsdsdsddssssdsSpringBoot:SpringBoot启动过程原理 ---- 25_第14张图片
sssdsddas ■ 初始化web服务器,比如Tomcat等(但开启是在注册完所有组件之后),创建容器中的所有组件(Spring注解)。
在这里插入图片描述
sssdsadas ⑩. 获取运行的时间。stopWatch.stop();

sssdsadas ⒒. 所有监听器调用 listeners.started(context); 通知所有的监听器 started

sssdsadas12. 调用所有runners;callRunners()
sssdssdsdadasSpringBoot:SpringBoot启动过程原理 ---- 25_第15张图片
sssdsadsaddas ■ 获取容器中的 ApplicationRunner
sssdsadsaddas ■ 获取容器中的 CommandLineRunner
sssdsadsaddas ■ 合并所有runner并且按照@Order进行排序
sssdsadsaddas ■ 遍历所有的runner。调用 run 方法
sssdsadas 13. 调用所有监听器的 running 方法 listeners.running(context); 通知所有的监听器 running

sssdsadas 14. 如果以上有异常,
sssdsadsaddas ■ 调用Listener 的 failed
sssdsadsddsas【注】:running如果有问题。继续通知 failed 。调用所有 Listener 的 failed;通知所有的监听器 failed

SpringBoot启动过程

ssss我们大致了解了SpringBoot启动过程后,就可以自定义一些组件,然后加载到SpringBoot的启动过程中。对应官方文档地址:https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.spring-application.application-events-and-listeners

ssss自定义:ApplicationContextInitializer初始化器,ApplicationListener,SpringApplicationRunListener监听器

ssss自定义:ApplicationRunner 与 CommandLineRunner 可以让我们做一些一次性事情。

你可能感兴趣的