SpringBoot启动流程、源码一步一步分析


启动入口代码示例:

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

启动流程图

springboot启动流程图

这里记录Springboot 2.x版本的启动流程,主要包含两个部分

第一个部分是创建SpringApplication对象,并对这个对象赋值操作,包括设置web应用类型、获取设置初始化器、获取设置监听器和设置mian方法所在主类;
第二个部分是执行run方法,包括获取监听器并发布各种事件、创建web容器上下文、准备上下文(执行初始化器)、刷新上下文(自动配置,创建Servlet容器并启动)、执行自定义run方法(ApplicationRunner、CommandLineRunner)等


接下来,逐个介绍各个步骤具体干了啥

创建SpringApplication对象

在mian方法中一般都是调用SpringApplication的静态run方法,并传入一个配置类和启动参数,这里其实是先new了一个SpringApplication对象实例,然后在调用run方法

在这里插入图片描述

2. 确定web应用类型

类型有3种:SERVLETREACTIVE(响应式)和NONE,根据应用中是否加载了相应的类,来确定web应用类型,如果项目引入了SERVLET的依赖,那么web应用类型就是SERVLET
在这里插入图片描述

3.获取并设置初始化器

从项目或者所有依赖jar包的META-INFO/spring.factories文件中查找以org.springframework.context.ApplicationContextInitializer为key的所有ApplicationContextInitializer实现类的全限定类名,并实例化这些对象,并设置给SpringApplication对象的initializers属性;这些ApplicationContextInitializer将会在后面用到,这里也是扩展点之一,这些初始化器会在步骤13被执行

在这里插入图片描述

META-INFO/spring.factories 文件中里面定义很多的相关类,当中就包含大家熟知的各种自动配置类,格式是以key=value形式展现,value以”,“分割,效果如下

在这里插入图片描述

Debug源码找到如下这些ApplicationContextInitializer实现类,共找到8个

在这里插入图片描述

它们分别是从spring-boot-devtools.jarspring-boot.jarspring-boot-autoconfigue.jar中的META-INFO/spring.factories 文件中获取得到的,刚好对应上面找到的8个

在这里插入图片描述

了解到这里我们也可以自己写一个类,实现ApplicationContextInitializer接口,放在项目的META-INFO/spring.factories 文件中,也是可以被读取到的

在这里插入图片描述

4.获取并设置监听器

获取方式跟上面步骤3一样,只不过这里获取org.springframework.context.ApplicationListener

在这里插入图片描述

5.确定main方法所在主类

借助于方法栈信息,确定main方法所在的类

在这里插入图片描述


执行run方法

执行run方法,传递args参数,即启动参数

在这里插入图片描述

7.创建计时器,记录启动时间

创建StopWatch对象,调用start方法记录SpringBoot启动时间

在这里插入图片描述

8.设置headless属性值

这里主要是设置系统属性java.awt.headless=true,目的是告诉系统,应用可以在无任何输入、输出设备,照样运行,一般作为服务器端是可以不需要显示器,键盘等输入、输出设备的

在这里插入图片描述

9.获取应用启动监听器并发布开始启动事件

获取方式跟步骤3一样,从META-INFO/spring.factories 文件中获取org.springframework.boot.SpringApplicationRunListener实现类,里面定义了一些方法,在应用启动过程中,用于发布对应启动过程的事件,如starting(应用启动事件)environmentPrepared(环境准备完毕事件)等;这里也可以做为一个扩展点,去实现org.springframework.boot.SpringApplicationRunListener接口对应的方法(注意:这里实现类需要有一个构造器,里面接收SpringApplication application, String[] args这2个参数),即监听到对应事件里做自己的业务逻辑;

在这里插入图片描述

这里获取到了springboot 的默认实现类EventPublishingRunListener,它实现了此接口,里面主要是应用到一个类SimpleApplicationEventMulticaster(事件多播器),通过它来发布事件;

自定义一个监听器

在这里插入图片描述

10.准备环境,获取设置系统配置、应用配置

根据步骤1确定的web应用类型创建不同的环境对象Environment,并获取系统环境配置,应用配置等信息,设置到环境对象中,以便后续使用

在这里插入图片描述
在这里插入图片描述

11.打印banner图

首先判断banner的打印模式(步骤1确定了为CONSOLE模式,即控制台打印)如果为OFF则不打印,接下来,会查看resources文件下是否有banner.txt或者banner.jpg(.png .gif),有的话,按照对应的打印模式打印相关的内容;如果没有,则执行默认的banner(SpringBootBanner)里面定义了字符串,字符串的内容就是我们熟知的默认banner效果
在这里插入图片描述
在这里插入图片描述

自定义banner效果图,在resources文件下放入banner.txt

在这里插入图片描述

12.创建web应用上下文

根据步骤1指定的web应用类型创建对应的web应用上下文

在这里插入图片描述
在这里插入图片描述

13.准备web应用上下文

主要是为web应用上下文设置一些属性值,包括环境environment应用初始化器(步骤1获取的初始化器,就是在这里调用的)、发布环境准备事件、注册参数和banner成组件到BeanFactory加载BeanBefinition(重要)、发布上下文加载完成事件等一系列内容

在这里插入图片描述

在这里插入图片描述

初始化器ApplicationContextInitializer,它里面有一个initialize方法,参数是context即上下文信息,拿到这个上下文那么不就可以想怎么改就怎么改了,前提是真正了解context,所以也是扩展点之一

14.刷新web应用上下文

这里就涉及到Spring的相关内容,总之会调用到AbstractApplicationContextrefresh方法,不过调用的发起者是步骤12创建的web应用上下文(如,AnnotationConfigServletWebServerApplicationContext),里面会重写refresh方法中的很多模板方法(留给子类重写的方法),如prepareRefreshpostProcessBeanFactoryonRefresh等;其中重写的onRefresh方法里面创建并启动了Servlet容器()(即,如内嵌Tomcat了解SpringBoot内置Servlet容器原理);自动配置功能也是在这一步骤完成了解SpringBoot自动配置
在这里插入图片描述

在这里插入图片描述
重写的onRefresh方法

在这里插入图片描述

15.执行自定义run方法

这里执行实现了ApplicationRunnerCommandLineRunner接口的run方法,也算是一个扩展点

在这里插入图片描述


总结

总之SpringBoot是基于Spring框架的,通过以上的分析知道每个步骤大致做了什么,以及有哪些扩展点,知道自动配置,以及内嵌Serlvet在哪一步执行……以上是对SpringBoot启动流程的大致说明,忽略了一些细节,并没有深入去分析,有错误之处,希望给予指导!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值