SpringApplication.run():启动流程的核心步骤

SpringApplication.run() 方法是启动的 “执行引擎”,大致分为初始化和运行两个阶段,流程如下:

阶段 1:初始化 SpringApplication 实例

在调用 run() 方法时,首先会创建 SpringApplication 对象,完成以下准备工作:
 
  • 推断应用类型:判断是 Web 应用(Servlet 或 Reactive)还是非 Web 应用(默认根据类路径是否存在 Servlet.class 等类判断)。
  • 加载初始化器(Initializer):从 META-INF/spring.factories 中加载 ApplicationContextInitializer 实现类,用于在容器刷新前初始化环境(如配置属性处理)。
  • 加载监听器(Listener):从 META-INF/spring.factories 中加载 ApplicationListener 实现类,用于监听启动过程中的各种事件(如启动开始、环境准备完成等)。
  • 确定主入口类:通过 main 方法所在的类定位应用入口。

阶段 2:执行启动流程(核心步骤)

  1. 启动监听器,发布启动事件
     
    通过 SpringApplicationRunListener 发布 ApplicationStartingEvent 事件,通知所有监听器 “应用开始启动”。
  2. 准备环境(Environment)
    • 加载系统环境变量、JVM 变量、命令行参数、配置文件(application.properties/yaml)等配置信息。
    • 发布 ApplicationEnvironmentPreparedEvent 事件,允许监听器修改环境配置。
  3. 创建并刷新 Spring 容器(ApplicationContext)
    • 根据应用类型创建对应的容器(如 AnnotationConfigServletWebServerApplicationContext 用于 Servlet 应用)。
    • 向容器中注入之前筛选出的自动配置类、用户定义的 Bean 等。
    • 刷新容器:执行 Spring 容器的核心初始化流程(如 Bean 的实例化、依赖注入、初始化方法调用等)。
  4. 启动嵌入式服务器
    • 若为 Web 应用,容器刷新时会触发 ServletWebServerFactory 自动配置(如 Tomcat、Jetty),创建并启动嵌入式服务器。
    • 服务器启动后,应用即可对外提供服务(如接收 HTTP 请求)。
  5. 执行自定义初始化逻辑
    • 容器刷新完成后,发布 ApplicationReadyEvent 事件。
    • 执行所有 CommandLineRunner 或 ApplicationRunner 接口的实现类(用户可通过这些接口在应用启动后执行初始化逻辑,如加载缓存)。

四、嵌入式服务器:为何 Spring Boot 可直接运行?

传统 Spring 应用需依赖外部容器(如独立的 Tomcat),而 Spring Boot 可直接运行,核心原因是内置了嵌入式服务器:
 
  • 依赖引入:spring-boot-starter-web 等 starter 默认引入 tomcat-embed-core 等依赖,将服务器打包进应用 JAR。
  • 自动配置:ServletWebServerFactoryAutoConfiguration 根据类路径中的服务器依赖(如 Tomcat),自动配置 TomcatServletWebServerFactory,在容器刷新时调用其 getWebServer() 方法启动服务器。

总结:启动原理的核心逻辑

Spring Boot 启动的本质是:
 
通过 @SpringBootApplication 整合配置与扫描逻辑,借助 @EnableAutoConfiguration 实现基于依赖的自动配置,再通过 SpringApplication.run() 封装容器初始化、服务器启动等流程,最终实现 “一键启动”。
 
其核心优势在于 “约定优于配置”:通过 starter 依赖约定组件,通过自动配置约定 Bean 注册规则,大幅减少了传统 Spring 应用的手动配置工作。
 
 
 
 
@EnableAutoConfiguration 的作用是:根据项目依赖(类路径中的 JAR 包)自动配置 Spring 容器中的 Bean,无需手动编写 XML 或 Java 配置。
 
其实现依赖以下机制:
 
  1. 导入自动配置选择器
     
    @EnableAutoConfiguration 内部通过 @Import(AutoConfigurationImportSelector.class) 导入一个核心处理器,该处理器的作用是筛选并加载符合条件的自动配置类。
  2. 加载候选自动配置类
     
    AutoConfigurationImportSelector 会扫描类路径下所有 META-INF/spring.factories 文件(Spring Boot 官方 starter 或第三方 starter 中定义),这些文件中声明了大量候选自动配置类(如 WebMvcAutoConfigurationDataSourceAutoConfiguration 等)。
     
    例如,spring-boot-autoconfigure 包中的 spring.factories 包含了数百个自动配置类的全类名。
  3. 条件筛选
     
    候选自动配置类并非全部生效,需通过 @Conditional 系列注解(Spring 的条件注解)判断是否符合当前环境:
    • @ConditionalOnClass:类路径中存在指定类时生效(如 WebMvcAutoConfiguration 依赖 Servlet.class)。
    • @ConditionalOnMissingBean:容器中不存在指定 Bean 时生效(允许用户自定义 Bean 覆盖自动配置)。
    • @ConditionalOnProperty:配置文件中存在指定属性时生效(如 spring.datasource.enabled=true)。最终,只有符合条件的自动配置类会被注入 Spring 容器,完成 Bean 的自动注册。
posted on 2025-10-11 16:10  从精通到陌生  阅读(1)  评论(0)    收藏  举报