Spring Boot 项目的启动流程,图片+文字详细解答(附相关面试题)

目录

一. 核心简要流程

二. 详细流程图

三. 启动流程详解

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 如何排除不需要的自动配置类?


一. 核心简要流程

  1. 启动类初始阶段 → 创建 SpringApplication → 初始化阶段(推断类型、加载配置)。

  2. 运行阶段 → 准备环境 → 创建上下文 → 刷新上下文(加载 Bean、启动服务器)→ 执行 Runner → 完成启动。

二. 详细流程图

其实相比于大量的文字描述,图形的方式是最易于大家理解的,我将 Spring Boot 的启动流程简化成了下面的一张图片,通过图片更易于同学们进行理解。

图片文字可能较小,这里我将图片的浏览器链接发到下面,有需要的小伙伴可以复制代码到浏览器查看。

Online FlowChart & Diagrams Editor - Mermaid Live Editor

流程代码

graph TD
    A[启动类 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)。具体步骤:

  1. 从类路径检测到 Servlet 类,触发 Web 应用类型推断。

  2. 通过 TomcatServletWebServerFactory 创建 Tomcat 实例,并绑定端口。

  3. 启动 Tomcat,此时服务器进入监听状态。

4.6 @SpringBootApplication 注解的作用是什么?

它是三个注解的组合:

  • @SpringBootConfiguration:标记为配置类。

  • @EnableAutoConfiguration:启用自动配置。

  • @ComponentScan:扫描当前包及其子包的 @Component 类。

4.7 Spring Boot 应用启动失败的可能原因及排查方法?

常见原因

  • 端口冲突:检查 server.port 是否被占用。

  • Bean 冲突:检查是否有重复的 Bean 定义。

  • 配置错误:如数据库连接信息错误。

  • 依赖缺失:检查 pom.xml 或 build.gradle 是否缺少必要依赖。

排查方法

  1. 查看启动日志中的异常堆栈信息。

  2. 启用调试模式:--debug 参数输出自动配置报告。

  3. 使用 @ConditionalOnProperty 或 @ConditionalOnMissingBean 分析条件是否满足。

4.8 如何排除不需要的自动配置类?

方法一:在 @SpringBootApplication 注解中通过 exclude 排除

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class Application { ... }

方法二:通过配置文件

spring:
  autoconfigure:
    exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
### Spring Boot 启动流程详解 #### 主启动类与注解解析 Spring Boot 应用程序通常由一个带有 `@SpringBootApplication` 注解的主启动类触发。这个注解是一个组合注解,它包含了其他几个重要的注解,如 `@Configuration`, `@EnableAutoConfiguration`, 和 `@ComponentScan`[^1]。 ```java @SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } } ``` 当应用程序启动时,`SpringApplication.run()` 方法会被调用来初始化并启动应用上下文。这一步骤涉及到加载配置、创建和刷新应用上下文等操作。 #### 初始化阶段 在初始化过程中,Spring Boot 执行了一系列的任务来设置环境变量、处理命令行参数以及检测是否存在特定条件下的自动配置需求。这些工作主要通过 `SpringApplication` 类中的方法完成,比如读取外部配置文件(`application.properties` 或者 `application.yml`)的内容,并将其转换为相应的 Java 属性对象[^4]。 #### 自动装配机制 Spring Boot 的一大特色就是其强大的自动装配能力。基于一系列预设好的规则——即所谓的“条件化配置”,框架可以根据当前项目的依赖关系和其他因素决定哪些 Bean 需要被实例化或注入到容器中。例如: - **@ConditionalOnBean**: 如果存在某些类型的 bean,则执行该逻辑;反之亦然。 这种灵活性使得开发者可以在不修改任何代码的情况下轻松切换不同的实现方式或是完全关闭某项特性。 #### Web 容器集成 对于 web 应用而言,在默认情况下 Spring Boot 不仅提供了内嵌式的 Tomcat 支持(无需额外安装服务器),而且允许用户选择 Jetty 或 Undertow 作为替代方案。这意味着即使没有传统意义上的 Servlet 容器支持,也能正常提供 HTTP 请求响应服务[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值