SpringBoot启动流程

主程序入口

启动类通常由@SpringBootApplication注解标注,主方法调用SpringApplication.run()

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

创建SpringApplication实例

  • SpringApplication是启动Spring Boot应用的核心类。它的构造方法会初始化:

    • 推断项目类型(web或者non-web)
    • 加载可用的ApplicationContextInitializer 和 ApplicationListener。
    • 推断主类(包含 main() 方法的类)。
  • 配置和启动

    • 调用SpringApplication.run()

      • 设置环境变量:创建和配置Environment,确定配置来源(application.properties、系统变量)
      • 创建 ApplicationContext:选择并实例化适合的 ApplicationContext(如 AnnotationConfigServletWebServerApplicationContext)。
      • 加载 Spring Boot 自动配置:通过 @EnableAutoConfiguration 和 META-INF/spring.factories 文件加载自动配置类。
      • 注册监听器:触发启动过程中的各种事件(如环境准备、上下文刷新等)。
    • 调用运行监听器

      • 在启动过程中,Spring Boot会发布以下主要事件

        • ApplicationStartingEvent

          • 用途:初始化日志系统、监控启动过程。
        • ApplicationEnvironmentPreparedEvent

          • 用途:配置文件加载后,可调整环境相关属性。
        • ApplicationContextInitializedEvent

          • 自定义 ApplicationContext 初始化逻辑。
        • ApplicationPreparedEvent

          • 准备 Bean 加载后的操作,比如调整某些 Bean 的定义。
        • ApplicationStartedEvent

          • 初始化与应用交互的资源或组件,比如外部监控工具。
        • ApplicationReadyEvent

          • 常用来执行启动后的业务逻辑,比如加载缓存或预热数据。
      • 开发者可以注册自定义的监听器以扩展应用
    • 加载所有 Bean 定义

      • 从配置类和自动配置类中扫描和加载 Bean 定义。
      • 完成依赖注入。
    • 启动嵌入式容器

      • 如果是web应用,启动嵌入式服务器(如Tomcat,Jetty)
    • 运行应用

      • 初始化完成之后,调用CommandLineRunner和ApplicationRunner接口中的实现方法,执行启动后的逻辑

底层实现原理

自动配置机制

@EnabledAutoConfiguation

  • @SpringBootApplication 包含 @EnabaleAutoConfiguration,负责自动配置应用所需要的Bean

SpringFactoriesLoader

  • SpringBoot使用SpringFactoriesLoader从META-spring.factories文件中加载配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
  • 这些自动配置类中会使用条件注解(@ConditionalOn*)判断是否启用特定功能。
嵌入式容器

默认支持嵌入式容器(Tomcat、jetty)

自动配置 ServletWebServerFactory 实现类,配置并启动Web容器

配置管理

application.yaml/application.properties

  • Spring Boot 自动加载 application.properties 或 application.yml 文件,覆盖优先级如下

    • 命令行参数
    • application.properties / application.yml 文件
    • @PropertySource 注解
    • 系统环境变量
    • 系统属性(System.getProperties)
  • @ConfigurationProperties

    • 支持将属性文件中的配置绑定到POJO,提供类型安全的配置
条件注解

Spring Boot的自动配置基于一系列条件注解完成

  • @ConditionalOnClass:当指定类存在时启用配置
  • @ConditionalOnMissingClass:当指定类不存在时启动配置
  • @ConditionOnBean:当指定的Bean存在时启动配置
  • @ConditionOnMissingBean:当指定的Bean不存在时启动配置
  • @ConditionOnProperty:当指定的属性存在且符合条件时启动配置
事件机制

Spring Boot在启动过程中会发布多个事件,开发者可以通过监听这些事件来扩展应用

常见事件包括

ApplicationStartingEvent:应用刚启动时触发
ApplicationReadyEvent:应用完全启动并准备好服务请求时触发。

通过监听器捕获事件:

@Component
public class CustomEventListener implements ApplicationListener<ApplicationReadyEvent> {
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        System.out.println(">>>>>> Application is ready!");
    }
}
SPI(服务提供者接口)机制

Spring Boot 使用 SPI 加载扩展点,比如 META-INF/spring.factories 和 META-INF/spring.components 文件,用于动态加载自动配置类、监听器等。

启动流程总结

  1. 初始化:创建SpringApplication实例,设置初始配置
  2. 环境准备,创建Environment,加载配置文件
  3. 上下文准备,初始化ApplicationContext,加载自动配置类
  4. 启动容器,加载Bean定义,启动嵌入式容器
  5. 完成启动,触发启动事件,执行启动后的回调逻辑

面试重点

  1. 启动的核心步骤

    • 环境准备,上下文加载,Bean的初始化,嵌入式容器启动
  2. @EnabledAutoConfiguration的底层实现

    • 调用SpringFactories动态加载自动配置类
  3. 条件注解的应用场景

    • 动态启用某些类的创建,取决于运行时条件
  4. 如何实现扩展

    • 监听SpringBoot启动过程中发布的一系列事件,注册监听器处理启动事件,或自定义 SpringApplicationRunListener。
  5. 如何调试自动配置?

    • 使用 spring-boot-starter-actuator的 /actuator/beans 或 /actuator/configprops 查看配置情况。

爱跑步的猕猴桃
1 声望0 粉丝