Spring Boot 启动流程机制详解

50 阅读5分钟

引言

Spring Boot 作为 Java 开发领域中广泛使用的框架,极大地简化了 Spring 应用的开发和部署过程。它通过自动配置和约定优于配置的原则,让开发者能够快速搭建和启动应用。深入了解 Spring Boot 的启动流程机制,有助于开发者更好地理解框架的工作原理,进行性能优化和问题排查。本文将详细剖析 Spring Boot 的启动流程,从启动类的入口开始,逐步深入到各个关键步骤。

Spring Boot 启动类

启动类的结构

在 Spring Boot 应用中,通常会有一个带有@SpringBootApplication注解的主类作为启动入口。以下是一个简单的示例:

image.png

@SpringBootApplication注解

@SpringBootApplication是一个组合注解,它包含了@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan三个重要的注解:

  • @SpringBootConfiguration:本质上就是@Configuration,用于标识该类是一个配置类。
  • @EnableAutoConfiguration:开启自动配置功能,Spring Boot 会根据项目中引入的依赖自动配置应用。
  • @ComponentScan:自动扫描指定包及其子包下的所有组件,将其注册到 Spring 容器中。

SpringApplication.run()方法

SpringApplication.run()方法是 Spring Boot 应用启动的核心方法,它接受应用的主类和命令行参数作为参数。该方法内部会创建一个SpringApplication实例,并调用其run()方法来启动应用。

Spring Boot 启动流程详解

1. 创建SpringApplication实例

当调用SpringApplication.run()方法时,首先会创建一个SpringApplication实例。在创建过程中,会进行以下操作:

  • 推断应用类型:根据类路径下的类来推断应用的类型,如 Web 应用(Servlet 或 Reactive)或非 Web 应用。
  • 查找并加载初始化器(ApplicationContextInitializer :初始化器用于在ApplicationContext刷新之前对其进行自定义配置。
  • 查找并加载监听器(ApplicationListener :监听器用于监听 Spring Boot 应用的各种事件,如应用启动、失败等。
  • 推断主应用类:通过分析调用栈来确定主应用类。

2. 调用SpringApplication.run()方法

创建SpringApplication实例后,会调用其run()方法,该方法的主要步骤如下:

2.1 记录启动时间

使用StopWatch记录应用的启动时间,方便后续统计启动耗时。

2.2 发布ApplicationStartingEvent事件

该事件标志着 Spring Boot 应用开始启动,所有注册的ApplicationListener会接收到该事件并进行相应的处理。

2.3 创建并配置环境(ConfigurableEnvironment

  • 创建环境对象:根据应用类型创建相应的环境对象,如StandardServletEnvironmentStandardReactiveEnvironment
  • 配置属性源:从命令行参数、系统属性、配置文件等多个来源加载属性,并将其添加到环境对象的属性源列表中。
  • 发布ApplicationEnvironmentPreparedEvent事件:通知所有监听器环境已经准备好。

2.4 创建ApplicationContext

根据应用类型创建相应的ApplicationContext,如AnnotationConfigServletWebServerApplicationContext(Servlet Web 应用)或AnnotationConfigReactiveWebServerApplicationContext(Reactive Web 应用)。

2.5 准备ApplicationContext

  • 设置环境:将之前创建的环境对象设置到ApplicationContext中。
  • 应用初始化器:调用所有注册的初始化器对ApplicationContext进行自定义配置。
  • 发布ApplicationContextInitializedEvent事件:通知所有监听器ApplicationContext已经初始化。

2.6 加载ApplicationContext

  • 扫描并注册组件:根据@ComponentScan注解的配置,扫描指定包及其子包下的所有组件,并将其注册到ApplicationContext中。
  • 加载自动配置类:根据@EnableAutoConfiguration注解的配置,加载所有符合条件的自动配置类。自动配置类会根据项目中引入的依赖和配置属性,自动配置应用的各种组件,如数据源、缓存等。

2.7 刷新ApplicationContext

  • 创建并初始化 BeanFactoryBeanFactory是 Spring 容器的核心,负责创建和管理所有的 Bean。
  • 注册 Bean 定义:将之前扫描和加载的组件注册为 Bean 定义,这些定义包含了 Bean 的元信息,如类名、作用域等。
  • 创建和初始化 Bean:根据 Bean 定义创建和初始化所有的 Bean,包括单例 Bean 和原型 Bean。
  • 启动嵌入式 Web 服务器(如果是 Web 应用) :如果应用是 Web 应用,会启动嵌入式 Web 服务器,如 Tomcat、Jetty 或 Undertow。

2.8 发布ApplicationStartedEvent事件

通知所有监听器应用已经启动。

2.9 调用CommandLineRunnerApplicationRunner

如果应用中定义了CommandLineRunnerApplicationRunner接口的实现类,会在应用启动后调用它们的run()方法,通常用于执行一些初始化任务。

2.10 发布ApplicationReadyEvent事件

通知所有监听器应用已经准备好接受请求。

3. 异常处理

如果在启动过程中发生异常,会发布ApplicationFailedEvent事件,通知所有监听器应用启动失败。

自动配置原理

Spring Boot 的自动配置是其核心特性之一,它通过@EnableAutoConfiguration注解实现。自动配置的原理如下:

  • META-INF/spring.factories文件:在 Spring Boot 的自动配置模块中,有一个META-INF/spring.factories文件,该文件中列出了所有的自动配置类。
  • 条件注解:自动配置类中使用了大量的条件注解,如@ConditionalOnClass@ConditionalOnMissingBean等。这些注解会根据类路径下的类、Bean 的存在情况等条件来决定是否应用该自动配置类。
  • 属性配置:自动配置类会根据配置文件中的属性来进行具体的配置,开发者可以通过修改配置文件来定制自动配置的行为。

总结

Spring Boot 的启动流程是一个复杂而又有序的过程,涉及到多个组件和步骤。通过深入了解其启动流程机制,开发者可以更好地理解框架的工作原理,进行性能优化和问题排查。同时,自动配置功能让开发者能够快速搭建和启动应用,提高开发效率。希望本文能够帮助开发者更好地掌握 Spring Boot 的启动流程和自动配置原理。