Springboot 启动流程及各类事件生命周期那点事
ztj100 2025-08-02 22:49 3 浏览 0 评论
前言
本文通过Springboot启动方法分析SpringApplication逻辑。从静态run方法执行到各个阶段发布不同事件完成整个应用启动。
SpringApplication 源码注释中说明了该类的主要作用,如下所示
启动逻辑详解
springboot应用在启动时存在两种方式:
第一种通过静态run方法直接启动
SpringApplication.run(MyApplication.class, args);
第二种通过创建对象后执行run方法启动
SpringApplication application = new SpringApplication(MyApplication.class);
application.run(args)
第二种方法其实就是第一种方法背后的逻辑。
在run方法执行过程中大量使用事件机制完成日志,配置文件,激活profile等工作,下图为整体执行流程图
- 通过SpringApplication静态run方法启动
- 初始化SpringApplication对象
- 设置资源加载器 (用于加载class文件,spring.factories文件)
- 设置primarysource
- 推断主类
- 通过SPI加载初始化器&监听器(稍后分析SPI实现逻辑)
- 执行run方法
- 加载SpringApplicationListner监听器,该监听器是是所有启动事件的发布者。此处与构造方法中加载的监听器作用不同
- SpringApplicationListner发布starting事件代表应用开始启动
- 包装应用启动参数
- 还在配置文件激活spring.active.profile对应的profile(感觉像是废话)发布enviromentPrepared事件
- 打印banner 默认是springboot ASCII编码
- 创建spring容器上下文
- 获取异常分析工厂类
- prepareContext 设置容器上下文
- 刷新容器获取工厂bean,工厂后置处理器,初始化单例bean
- 调用afterResfresh方法
- 发布启动完成事件
- 回调callRunner方法
- 发布应用运行中事件
Springboot SPI 分析
在初始化SpringApplication对象时通过springboot SPI方式对classpath下所有jar包中 META-INF/spring.factories文件进行加载,这也是springboot自动装配中使用到的逻辑。
在构造方法中 通过
getSpringFactoriesInstances完成工厂类加载与初始化。
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
return getSpringFactoriesInstances(type, new Class<?>[] {});
}
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = getClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
getSpringFactoriesInstances方法中通过一个单例类SpringFactoriesLoader完成所有META-INF/spring.factories文件的读取。通过classLoader.getResources方法读取classpath下所有jar包后队文件进行解析。
spring.factories文件内容为key value对,多个value用逗号分隔,如下所示
# Spring Test ContextCustomizerFactories
org.springframework.test.context.ContextCustomizerFactory=\
org.springframework.boot.test.context.ImportsContextCustomizerFactory,\
org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizerFactory,\
org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory,\
org.springframework.boot.test.mock.mockito.MockitoContextCustomizerFactory,\
org.springframework.boot.test.web.client.TestRestTemplateContextCustomizerFactory,\
org.springframework.boot.test.web.reactive.server.WebTestClientContextCustomizerFactory
# Test Execution Listeners
org.springframework.test.context.TestExecutionListener=\
org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener,\
org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.test.web.SpringBootTestRandomPortEnvironmentPostProcessor
接下来是启动逻辑的重点run方法。本文重点分析run方法中事件触发逻辑。
Spingboot 事件机制详解
在run方法中通过getRunListeners方法加载事件监听器,该监听器负责发布应用启动中各个阶段的状态
- starting 阶段
- environmentPrepare阶段 负责配置文件,系统环境变量,激活profile等逻辑
- contextPrepared 阶段负责初始化applicationContext
- contextLoaded 阶段 applicationContext加载所有单例bean
- started 阶段 应用启动完成
- running 阶段 应用运行中状态
getRunListeners通过
getSpringFactoriesInstances方法加载
SpringApplicationRunListener所有实现类,该接口默认实现类为
EventPublishingRunListener,该类包含如下方法
方法中通过
SimpleApplicationEventMulticaster类发送通知,该类名也能表示其作用:简单应用事件多播器,翻译出来总感觉差点意思。在run 方法中存在以上6个listener方法调用的逻辑。
下图中列出了监听器处理的部分事件,由于事件监听器过多在此不展开分析
总结
通过整体启动分析将整个启动流程进行梳理,有助于大家在阅读源码前掌握正义的概要避免陷入局部逻辑无法自拔。
后面将会针对不同的逻辑进行深入分析。
相关推荐
- Java的SPI机制详解
-
作者:京东物流杨苇苇1.SPI简介SPI(ServiceProvicerInterface)是Java语言提供的一种接口发现机制,用来实现接口和接口实现的解耦。简单来说,就是系统只需要定义接口规...
- 一文读懂 Spring Boot 启动原理,开发效率飙升!
-
在当今的Java开发领域,SpringBoot无疑是最热门的框架之一。它以其“约定大于配置”的理念,让开发者能够快速搭建和启动应用,极大地提高了开发效率。但是,你是否真正了解Spring...
- ServiceLoader
-
ServiceLoader是Java提供的一种服务发现机制(ServiceProviderInterface,SPI)...
- 深入探索 Spring Boot3 中的自定义扩展操作
-
在当今互联网软件开发领域,SpringBoot无疑是最受欢迎的框架之一。随着其版本迭代至SpringBoot3,它为开发者们带来了更多强大的功能和特性,其中自定义扩展操作更是为我们在项目开发中...
- Spring Boot启动过程全面解析:从入门到精通
-
一、SpringBoot概述SpringBoot是一个基于Spring框架的快速开发脚手架,它通过"约定优于配置"的原则简化了Spring应用的初始搭建和开发过程。...
- Spring Boot 3.x 自定义 Starter 详解
-
今天星期六,继续卷springboot3.x。在SpringBoot3.x中,自定义Starter是封装和共享通用功能、实现“约定优于配置”理念的强大机制。通过创建自己的Starte...
- Spring Boot 的 3 种动态 Bean 注入技巧
-
在SpringBoot开发中,动态注入Bean是一种强大的技术,它允许我们根据特定条件或运行时环境灵活地创建和管理Bean。相比于传统的静态Bean定义,动态注入提供了更高的灵活性和可...
- 大佬用4000字带你彻底理解SpringBoot的运行原理!
-
SpringBoot的运行原理从前面创建的SpringBoot应用示例中可以看到,启动一个SpringBoot工程都是从SpringApplication.run()方法开始的。这个方法具体完成...
- Springboot是如何实现自动配置的
-
SpringBoot的自动配置功能极大地简化了基于Spring的应用程序的配置过程。它能够根据类路径中的依赖和配置文件中的属性,自动配置应用程序。下面是SpringBoot实现自动配置的...
- Spring Boot3.x 应用的生命周期深度解析
-
SpringBoot应用的生命周期可以清晰地划分为三个主要阶段:启动阶段(Startup)...
- Springboot 启动流程及各类事件生命周期那点事
-
前言本文通过Springboot启动方法分析SpringApplication逻辑。从静态run方法执行到各个阶段发布不同事件完成整个应用启动。...
- Spring框架基础知识-常用的接口1
-
BeanDefinition基本概念BeanDefinition是Spring框架中描述bean配置信息的核心接口,它包含了创建bean实例所需的所有元数据。...
- Java 技术岗面试全景备战!从基础到架构的系统性通关攻略分享
-
Java技术岗的面试往往是一项多维度的能力检验。本文将会从核心知识点、项目经验到面试策略,为你梳理一份系统性的备战攻略!...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)