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启动流程的大致说明,忽略了一些细节,并没有深入去分析,有错误之处,希望给予指导!!!

<think>嗯,用户让我结合源码总结SpringBoot启动流程。首先,我得回忆一下SpringBoot启动的关键步骤,然后对应到源码里的具体类方法。可能需要从main方法开始,逐步分析。 首先,SpringBoot应用的入口通常是带有@SpringBootApplication注解的主类,然后调用SpringApplication.run()方法。这一步应该触发整个启动流程。需要确认SpringApplication类的结构,特别是run方法里面的步骤。 我记得SpringApplication的初始化阶段会加载应用上下文,读取配置,可能还涉及到事件监听机制。比如,准备环境、创建应用上下文、刷新上下文这些步骤。需要具体到源码中的方法调用顺序,比如prepareEnvironment、refreshContext等。 另外,自动配置是SpringBoot的重要特性,所以需要提到@EnableAutoConfiguration如何通过spring.factories加载配置类。可能涉及到SpringFactoriesLoader的源码,还有条件注解的处理,比如@ConditionalOnClass。 还有内嵌Servlet容器的启动,比如Tomcat,这部分可能在刷新应用上下文的时候触发,具体在ServletWebServerApplicationContext中。需要看看如何初始化Tomcat,并启动它。 用户要求结合源码,所以最好能提到关键的类方法的名称,比如SpringApplication.run()、ApplicationContextInitializer、ApplicationListener、ConfigurableEnvironment、AbstractApplicationContext.refresh()等。 可能需要分步骤详细说明每个阶段做了什么,比如实例化SpringApplication,配置环境,准备上下文,执行Runners等。还要注意事件驱动的部分,比如ApplicationStartingEvent在run方法的不同阶段发布事件,通知监听器。 另外,用户可能希望了解启动流程中的扩展点,比如ApplicationRunnerCommandLineRunner的执行时机,或者自定义的InitializersListeners如何被调用。 总结的时候要结构清晰,按启动顺序分点,每个点对应源码中的关键步骤,并简要说明其作用。确保覆盖从启动类开始到应用完全启动的整个流程,包括自动配置、Bean加载、内嵌服务启动等核心环节。</think>结合Spring Boot 2.x源码,我将核心启动流程总结如下(关键方法用`代码块`标注): --- ### 一、入口阶段 ```java @SpringBootApplication public class MyApp { public static void main(String[] args) { SpringApplication.run(MyApp.class, args); // 入口方法 } } ``` --- ### 二、SpringApplication初始化 1. **资源加载** ```java // SpringApplication构造方法 this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); this.webApplicationType = WebApplicationType.deduceFromClasspath(); // 判断WEB环境 ``` 2. **加载初始化器** ```java setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class)); // META-INF/spring.factories加载 ``` --- ### 三、run()方法核心流程 ```java public ConfigurableApplicationContext run(String... args) { // 1. 启动计时器 StopWatch stopWatch = new StopWatch(); // 2. 准备环境 ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArgs); // 3. 打印Banner Banner printedBanner = printBanner(environment); // 4. 创建应用上下文 context = createApplicationContext(); // 5. 准备上下文 prepareContext(context, environment, listeners, applicationArgs, printedBanner); // 6. 刷新上下文(核心) refreshContext(context); // 7. 执行Runners callRunners(context, applicationArgs); return context; } ``` --- ### 四、关键扩展点实现 1. **自动配置原理** ```java // @SpringBootApplication -> @EnableAutoConfiguration List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); // 加载spring.factories中的配置类 // AutoConfigurationImportSelector.selectImports() List<String> configurations = SpringFactoriesLoader.loadFactoryNames( EnableAutoConfiguration.class, this.beanClassLoader); ``` 2. **内嵌Web容器启动** ```java // ServletWebServerApplicationContext.refresh() WebServer webServer = startWebServer(); // 启动Tomcat/Jetty/Undertow // TomcatServletWebServerFactory.getWebServer() Tomcat tomcat = new Tomcat(); tomcat.start(); // 启动Tomcat ``` --- ### 五、事件驱动机制 ```java // 事件发布顺序: 1. ApplicationStartingEvent 2. ApplicationEnvironmentPreparedEvent 3. ApplicationContextInitializedEvent 4. ApplicationPreparedEvent 5. ApplicationStartedEvent 6. ApplicationReadyEvent // 监听器实现 public class MyListener implements ApplicationListener<ApplicationEvent> { @Override public void onApplicationEvent(ApplicationEvent event) { // 处理事件 } } ``` --- ### 六、启动流程图 ``` main() ├─ SpringApplication构造 │ ├─ 推断WEB类型 │ └─ 加载Factories配置 ├─ run() │ ├─ 准备Environment │ ├─ 创建ApplicationContext │ ├─ 刷新Context(核心) │ │ ├─ BeanFactory初始化 │ │ ├─ 执行BeanFactoryPostProcessor │ │ ├─ 注册BeanPostProcessor │ │ ├─ 初始化MessageSource │ │ ├─ 初始化事件广播器 │ │ ├─ 初始化Servlet容器 │ │ └─ 发布ContextRefreshedEvent │ └─ 执行Runners └─ 返回运行中的Context ``` --- ### 七、核心源码类 1. `SpringApplication`:启动入口 2. `ConfigurableApplicationContext`:应用上下文 3. `AbstractApplicationContext.refresh()`:刷新方法 4. `SpringFactoriesLoader`:工厂加载器 5. `AutoConfigurationImportSelector`:自动配置选择器 建议结合`org.springframework.boot.SpringApplication``org.springframework.context.support.AbstractApplicationContext`源码阅读,重点关注`refresh()`方法的12个标准步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值