Skip to content

说说 Springboot 的启动流程? ​

  • 标签:Java、Spring Boot、后端

🏛 业务架构师 ​

Spring Boot 启动流程我按业务可感知的四个阶段讲:

  1. SpringApplication.run 入口准备:推断应用类型、加载 environment(配置文件+环境变量+启动参数的多环境体系在此生效)、打印 banner、创建 ApplicationContext;
  2. 准备上下文:注册启动类为配置源,解析 @SpringBootApplication 里的 @ComponentScan 确定扫描包——包结构决定了 bean 装配范围,基础包配错是经典事故;
  3. refresh 核心:
    • 执行 BeanFactoryPostProcessor,其中 @EnableAutoConfiguration 触发自动配置导入(AutoConfiguration.imports 清单 + @Conditional 条件过滤,classpath 里有什么 starter 就装什么 bean);
    • 注册 BeanPostProcessor(后续 @Autowired、@PostProcessor 都靠它们织入);
    • onRefresh 启动内嵌 Tomcat;
    • 实例化所有非懒加载单例(实例化 → 属性注入 → aware 回调 → 初始化);
  4. 收尾:发布 ready 事件、执行 ApplicationRunner——业务预热(缓存预载、强依赖校验 fail-fast)的标准挂点。

业务视角的两点体会:

  • 启动速度是交付效率的一部分:滚动发布的批次时长、弹性扩容速度、Serverless 冷启动都受它制约。治理手段:懒加载、StartupActuator 分析 bean 耗时、拆不必要的 starter;
  • 自动配置是"约定优于配置"的商业逻辑:它把"搭一个能跑的服务"从三天压到三分钟,新人上手成本骤降——框架竞争的本质是组织效率竞争,Spring Boot 赢在这里。

🏗 系统架构师 ​

Spring Boot 启动入口就一句 SpringApplication.run(App.class, args),但内部链路我拆成四段:

  1. SpringApplication 构造:推断应用类型(Servlet / Reactive / 普通,依据 classpath 有无内嵌容器类);通过 SpringFactoriesLoader 加载 ApplicationContextInitializer、ApplicationListener;确定 mainClass;
  2. 环境准备:创建并配置 Environment(加载 application.yml、外部化配置、环境变量,按优先级覆盖),打印 Banner;
  3. 创建并 refresh 容器:按应用类型建 ApplicationContext(Servlet 是 AnnotationConfigServletWebServerApplicationContext);执行初始化器;refresh() 内部:处理 @Configuration → 注册 BeanDefinition → invokeBeanFactoryPostProcessors(关键一步:@EnableAutoConfiguration 引入的自动配置在这里被解析,条件注解筛选生效配置)→ 注册 BPP → onRefresh 里创建并启动内嵌 Tomcat(绑定端口)→ 实例化单例 Bean;
  4. 收尾:发布 ready 事件、执行 ApplicationRunner/CommandLineRunner、容器就绪对外服务。

面试抓手:自动配置生效时机(BFPP 阶段)、内嵌容器启动时机(onRefresh)、Runner 执行时机(容器就绪后),三个"时机"答准了就超过大多数人。

💻 全栈开发专家 ​

一条主线:SpringApplication.run() = 准备阶段 + refresh() + 收尾。

1. 构造 SpringApplication:推断应用类型(SERVLET / REACTIVE / 普通),加载 ApplicationContextInitializer 和 ApplicationListener(spring.factories 机制),决定 banner。

2. 环境准备:创建 ConfigurableEnvironment,把命令行参数、系统变量、application.yml 按优先级合并进 PropertySource;触发 ApplicationEnvironmentPreparedEvent——ConfigFileApplicationListener 在这里加载 application.yml。

3. 创建并准备 ApplicationContext:实例化容器,environment 注入,执行 initializers;load 主类(把 @SpringBootApplication 标注的启动类注册为 BeanDefinition)。

4. refreshContext(核心):走 Spring 的 refresh 流程,其中 invokeBeanFactoryPostProcessors 阶段触发自动配置(AutoConfigurationImportSelector 导入所有 autoconfigure 类);onRefresh 阶段创建内嵌 Tomcat;finishBeanFactoryInitialization 实例化单例 Bean。

5. 收尾:发布 ContextRefreshedEvent → 启动 webserver 并绑定端口 → 发布 ApplicationReadyEvent → 执行 ApplicationRunner/CommandLineRunner。

排障经验:启动慢用 Actuator 的 /startup(ApplicationStartup 指标)定位到具体 Bean;Runner 里适合做预热(缓存加载),但别放重活,会拖慢就绪探针。