目录
一. 核心简要流程
二. 详细流程图
三. 启动流程详解
3.1 初始化阶段
3.2 运行阶段
四. 面试题合集
4.1 Spring Boot启动流程?
4.2 Spring Boot 的自动配置是如何实现的?
4.3 如何自定义 Spring Boot 的 Banner?
4.4 如何监听 Spring Boot 的启动事件?
4.5 Spring Boot 内嵌服务器是如何启动的?
4.6 @SpringBootApplication 注解的作用是什么?
4.7 Spring Boot 应用启动失败的可能原因及排查方法?
4.8 如何排除不需要的自动配置类?
一. 核心简要流程
-
启动类初始阶段 → 创建
SpringApplication
→ 初始化阶段(推断类型、加载配置)。 -
运行阶段 → 准备环境 → 创建上下文 → 刷新上下文(加载 Bean、启动服务器)→ 执行 Runner → 完成启动。
二. 详细流程图
其实相比于大量的文字描述,图形的方式是最易于大家理解的,我将 Spring Boot 的启动流程简化成了下面的一张图片,通过图片更易于同学们进行理解。
图片文字可能较小,这里我将图片的浏览器链接发到下面,有需要的小伙伴可以复制代码到浏览器查看。
Online FlowChart & Diagrams Editor - Mermaid Live Editor
流程代码
graph TDA[启动类 main 方法] --> B[创建 SpringApplication 实例]B --> C[初始化阶段]C --> C1[推断应用类型]C --> C2[加载 SpringFactories]C --> C3[设置主类]B --> D[运行阶段 run()]D --> D1[启动计时器]D1 --> D2[配置 Headless 模式]D2 --> D3[发布 ApplicationStartingEvent]D3 --> D4[准备环境 Environment]D4 --> D4a[加载配置文件 application.yml]D4 --> D4b[加载命令行参数]D4 --> D4c[发布 ApplicationEnvironmentPreparedEvent]D4 --> D5[打印 Banner]D5 --> D6[创建 ApplicationContext]D6 --> D7[初始化上下文]D7 --> D7a[调用 ApplicationContextInitializer]D7 --> D7b[发布 ApplicationContextInitializedEvent]D7 --> D8[刷新上下文 refresh()]D8 --> D8a[准备 BeanFactory]D8 --> D8b[执行 BeanFactoryPostProcessor]D8b --> D8b1[处理 @Configuration 类]D8b --> D8b2[加载自动配置 AutoConfiguration]D8 --> D8c[注册 BeanPostProcessor]D8 --> D8d[初始化 MessageSource]D8 --> D8e[初始化事件广播器]D8 --> D8f[实例化单例 Bean]D8f --> D8f1[创建 Controller/Service/Repository]D8f --> D8f2[启动内嵌服务器 Tomcat/Jetty]D8 --> D8g[发布 ContextRefreshedEvent]D8g --> D9[执行 CommandLineRunner/ApplicationRunner]D9 --> D10[发布 ApplicationReadyEvent]D10 --> E[应用启动完成]
不过,只看图片是不够哒,所以小编这里还是要进行文字说明,文字结合图片,相信大家对于Spring Boot 的启动流程能有一个更清晰的理解!
下面我们进入正题
三. 启动流程详解
Spring Boot 项目启动流程可以分为初始化阶段和运行阶段,核心逻辑在 SpringApplication.run() 方法中,此方法涵盖了整个运行阶段。
下面我们对这两个阶段以及做了哪些事分别进行解析。
3.1 初始化阶段
项目初始启动,会在当前工作目录下寻找带有 @SpringBootApplication 注解的标识启动类,并把这个类作为应用程序的入口点,如果没有找到带有 @SpringBootApplication 注解的标识类,则会报错并打印错误信息。
在初始化过程中,实例对象由 SpringApplication 的构造函数进行初始化,主要做一下三件事:
(1)推断应用类型:根据类路径判断是 Web 应用(Servlet,Reactive)还是普通应用。
(2)加载 SpringFactories:通过 SpringFactoriesLoader 加载 META-INF / spring.factories 文件中定义的配置类,包括
ApplicationContextInitializer:应用上下文初始化器
ApplicationListener:应用事件监听器(如监听启动事件)。
(3)设置主类:通过 StackTrace
找到 main
方法所在的类(即启动类)。
3.2 运行阶段
找到 main 方法以后,程序就会执行 main 中 run()方法, 完成以下关键步骤。
步骤一:启动计时器
主要负责记录应用启动耗时,用于监控和日志输出。
步骤二:配置 Headless模式
设置 java.awt.headless = true,使服务器没有显示器和鼠标也能运行。
步骤三:创建并发布 ApplicationStartingEvent 事件
通知所有 ApplicationListener 监听器应用开始启动
步骤四:准备程序运行环境(Environment)
读取配置:加载 application.yml,application.properties 配置文件,命令行参数系统环境变量等。
读取并准备完毕后,发布 ApplicationEnvironmentPreparedEvent 事件,表明环境已准备就绪。
步骤五:打印 Banner,显示 Spring Boot启动图标
如下图所示,该图标也可通过 banner.txt 文件自定义,但一般很少会这样做就是啦。
步骤六:创建应用上下文 ApplicationContext
在最开始程序初始化的时候,已经判断了应用的类型,然后这里就会根据应用等各类型创建对应的 ApplicationContext。
Servlet应用:创建 AnnotationConfigServletWebServerApplicationContext;
Reactive 应用:创建 AnnotationConfigReactiveWebServerApplicationContext;
普通应用:创建 AnnotationConfigApplicationContext;
步骤七:初始化应用上下文
调用 ApplicationContextInitializer 对上下文进行预处理,例如注册自定义 Bean。
然后发布 ApplicationContextInitializedEvent 事件,表明上下文初始化已完成。
步骤八:刷新应用上下文(核心步骤,注册 Bean 对象)
(1)准备上下文:设置上下文环境(Environment);
(2)解析配置类:通过@ComponentScan 扫描 Bean,加载 @Configuration 配置类。
(3)执行 BeanFactoryPostProcessor :
处理 @PropertySource、@Import 等注解。
自动配置的核心:加载 spring.factories 中的 AutoConfiguration 类,根据条件(例如@ConditionalOnClass) 动态注册 Bean。
(4)注册 BeanPostProcessor 处理 Bean 初始化前后的逻辑(例如AOP逻辑)。
(5)初始化消息源(MessageSource):国际化支持。
(6)初始化时间广播器:用于发布事件。
(7)实例化单例 Bean 对象:调用 finishBeanFactoryInitialization() ,创建所有非懒加载的单例 Bean。
(8)启动内嵌服务器:如果是 Web 应用,Spring Boot 会启动一Web 服务器(例如 Tomcat、Jetty 、Undertow)
具体决定启动哪个服务器,是通过 ServletWebServerFactoryAutoConfiguration 配置类结合 条件注解 @ConditionalOnClass 动态选择的。
如果类路径存在 Tomcat 类,默认依赖 spring-boot-starter-web
包含 tomcat-embed-core。
则会使用 Tomcat。
如果排除 Tomcat 并添加 Jetty 或 Undertow 依赖,则自动切换。
(9)完成上下文刷新:发布 ContextRefreshedEvent 事件,表明容器刷新事件已完成
步骤九:所有实现这两个接口的 Bean执行 CommandLineRunner 和 ApplicationRunner,用于启动后执行自定义逻辑
步骤十:发布 ApplicationStartedEvent 和 ApplicationReadyEvent,通知应用已完全启动
四. 面试题合集
4.1 Spring Boot启动流程?
精炼回答:
Spring Boot 启动流程分为初始化阶段和运行阶段。初始化阶段通过 SpringApplication
构造函数加载配置类和推断应用类型;运行阶段通过 run()
方法依次完成环境准备、上下文创建、Bean 加载、自动配置、启动内嵌服务器等操作。核心步骤包括读取配置、刷新上下文(加载 Bean)、执行 Runner 接口,最终发布启动完成事件。
4.2 Spring Boot 的自动配置是如何实现的?
自动配置通过 @EnableAutoConfiguration
注解触发,其底层依赖 spring.factories
文件中定义的 AutoConfiguration
类。这些类使用 @Conditional
注解(如 @ConditionalOnClass
、@ConditionalOnMissingBean
)根据类路径、配置等条件动态注册 Bean。例如,当类路径存在 DataSource
时,自动配置数据源相关的 Bean。
4.3 如何自定义 Spring Boot 的 Banner?
在 src/main/resources
下创建 banner.txt
文件,Spring Boot 启动时会自动读取该文件内容作为 Banner。此外,可通过 spring.banner.location
指定自定义文件路径,或通过 SpringApplication.setBanner()
以编程方式设置。
4.4 如何监听 Spring Boot 的启动事件?
实现 ApplicationListener
接口并监听特定事件,例如:
-
ApplicationStartingEvent
:应用启动时(此时 Bean 尚未加载)。 -
ApplicationReadyEvent
:应用完全启动后。
或使用 @EventListener
注解:
@EventListener(ApplicationReadyEvent.class)
public void onReady() {System.out.println("应用已启动!");
}
4.5 Spring Boot 内嵌服务器是如何启动的?
在刷新上下文时,Spring Boot 会通过 ServletWebServerApplicationContext
的 onRefresh()
方法创建内嵌服务器(如 Tomcat)。具体步骤:
-
从类路径检测到
Servlet
类,触发 Web 应用类型推断。 -
通过
TomcatServletWebServerFactory
创建 Tomcat 实例,并绑定端口。 -
启动 Tomcat,此时服务器进入监听状态。
4.6 @SpringBootApplication
注解的作用是什么?
它是三个注解的组合:
-
@SpringBootConfiguration
:标记为配置类。 -
@EnableAutoConfiguration
:启用自动配置。 -
@ComponentScan
:扫描当前包及其子包的@Component
类。
4.7 Spring Boot 应用启动失败的可能原因及排查方法?
常见原因:
-
端口冲突:检查
server.port
是否被占用。 -
Bean 冲突:检查是否有重复的 Bean 定义。
-
配置错误:如数据库连接信息错误。
-
依赖缺失:检查
pom.xml
或build.gradle
是否缺少必要依赖。
排查方法:
-
查看启动日志中的异常堆栈信息。
-
启用调试模式:
--debug
参数输出自动配置报告。 -
使用
@ConditionalOnProperty
或@ConditionalOnMissingBean
分析条件是否满足。
4.8 如何排除不需要的自动配置类?
方法一:在 @SpringBootApplication
注解中通过 exclude
排除
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class Application { ... }
方法二:通过配置文件
spring:autoconfigure:exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration