Spring spring

Spring中文网站 > Spring Boot > Spring Boot的启动流程是什么 Spring Boot的启动原理解析
Spring Boot的启动流程是什么 Spring Boot的启动原理解析
发布时间:2026/02/08 10:54:49

  很多人第一次看Spring Boot启动,会觉得只写了一行SpringApplication.run就把应用带起来了,但日志里又出现了一堆事件、环境加载与自动配置输出,越看越像黑盒。把启动拆成明确的阶段,再把每个阶段对应到Spring Framework的容器刷新流程,你就能解释清楚为什么它能自动装配、为什么某些配置会生效或失效,也更容易定位启动慢与卡住的根因。

  一、Spring Boot的启动流程是什么

 

  Spring Boot的启动流程可以用一条主线串起来:准备启动器与扩展点,准备环境与属性源,创建ApplicationContext,上下文refresh刷新完成Bean装配,然后进入可服务状态并发布就绪信号。你只要抓住这些阶段边界,很多日志就能对上号。

 

  1、入口从main方法进入到SpringApplication.run

 

  典型启动类在main里调用SpringApplication.run,run是一次启动编排的总入口,负责把环境准备、上下文创建、监听器回调、容器刷新这些动作串成一条稳定的时间线。

 

  2、构造SpringApplication时先确定应用类型与基础配置

 

  SpringApplication在初始化阶段会识别应用类型,例如普通应用、Servlet Web应用、Reactive Web应用,并据此决定后续要创建哪种ApplicationContext,这一步决定了你最终看到的是哪类WebServer与哪套启动事件顺序。

 

  3、启动早期加载监听器与初始化器,建立可插拔的启动钩子

 

  run开始后会先装载一批启动期扩展组件,例如ApplicationContextInitializer与ApplicationListener,它们会在Environment准备前后、Context创建前后被回调,方便你在不侵入业务代码的情况下做早期定制。

 

  4、准备Environment并合并外部化配置

 

  启动会构建Environment,把命令行参数、配置文件、系统属性、环境变量等属性源合并进来,并按优先级形成统一的属性读取口径,后续的条件装配与自动配置判断都基于这份Environment做决策。

 

  5、创建ApplicationContext并执行refresh刷新容器

 

  Spring Boot会创建对应的ApplicationContext,并执行refresh,refresh内部会完成BeanDefinition处理、BeanFactory后处理器执行、Bean后处理器注册、单例Bean初始化、事件广播等核心动作,Web应用还会在合适阶段创建并启动内嵌WebServer。

 

  6、启动完成后进入可用状态并触发Runner

 

  容器refresh完成后,应用会进入Started阶段,随后执行CommandLineRunner与ApplicationRunner这类一次性启动任务,等这些任务结束后才会进入Ready阶段,你在健康检查与就绪探针里看到的状态变化通常与这里对应。

 

  二、Spring Boot的启动原理解析

 

  Spring Boot的启动原理可以拆成三层:第一层是SpringApplication负责生命周期编排,第二层是Spring Framework的refresh负责容器初始化模板流程,第三层是自动配置把依赖与环境映射成一组可条件生效的配置类。理解这三层之间的分工,你就不会把所有现象都归结为自动配置。

 

  1、SpringApplication负责把启动拆成可控阶段并统一对外暴露扩展点

 

  SpringApplication把启动拆成若干稳定阶段,并在每个阶段发布事件或执行回调,这让你能在正确时点介入,例如在Environment准备后补属性源,在Bean装配前调整上下文初始化逻辑,在应用就绪后启动异步任务。

  2、自动配置的候选收集依赖类路径发现机制

 

  EnableAutoConfiguration对应的候选配置类并不是写死在你的应用里,而是从类路径上收集出来,再交给后续的条件判断筛选,这也是为什么引入一个starter依赖后,很多默认Bean会自动出现。

 

  3、条件装配决定自动配置是否生效

 

  自动配置本质还是普通的Configuration配置类,只是大量使用ConditionalOnClass、ConditionalOnMissingBean、ConditionalOnProperty等条件注解,启动时会根据当前依赖、环境属性、已存在Bean进行评估,评估通过才会注册对应Bean。

 

  4、refresh是容器启动的核心模板方法

 

  refresh负责把BeanDefinition的处理链路跑完,再把Bean生命周期的关键节点串起来,包括后处理器、事件系统、单例初始化等,Spring Boot并没有改写这套核心机制,而是把上下文准备好并把refresh作为启动的关键关口。

 

  5、Web应用的关键是内嵌容器与上下文的组合

 

  在Servlet Web模式下,ServletWebServerApplicationContext会在容器中寻找ServletWebServerFactory并创建WebServer,再把DispatcherServlet与相关组件装配进去,最终形成可对外提供HTTP服务的运行形态,内嵌服务器之所以能随应用启动,本质原因就在这条链路上。

 

  6、启动日志与事件能反推卡点位置

 

  当你遇到启动慢或卡住,优先把现象映射到阶段上,例如卡在Environment阶段通常与配置源或网络配置中心有关,卡在refresh阶段通常与Bean初始化、条件评估或扫描范围有关,卡在WebServer阶段通常与端口占用、容器初始化或过滤器链有关。

 

  三、Spring Boot启动扩展点与排查落点

 

  理解原理之后,真正有价值的是把扩展与排查落到稳定点位上,避免把逻辑写进不可控的时机,导致顺序混乱或条件判断被破坏。你可以把常见需求分成环境定制、容器定制、启动任务、启动观测四类来放置。

 

  1、需要改环境与属性源就放在Environment准备阶段

 

  如果你要注入额外配置源、修正某些默认属性、合并多套配置口径,更适合在Environment已准备但容器未refresh的阶段完成,这样后续条件装配能读到一致的配置视图。

 

  2、需要改BeanDefinition就使用BeanFactory后处理器

 

  当你要批量注册BeanDefinition、调整扫描到的定义、替换某些默认定义,选择BeanFactoryPostProcessor这类机制更稳,它在单例实例化前执行,改动影响范围清晰,也更容易与自动配置共存。

 

  3、需要增强Bean行为就使用Bean后处理器

 

  如果你的目标是对某类Bean做代理增强、注入额外逻辑、修正初始化后的状态,使用BeanPostProcessor更合适,它作用在实例化前后,不会把启动顺序搞乱,也能把增强逻辑从业务代码里抽离出来。

 

  4、一次性启动任务优先用Runner来承载

 

  需要在应用可用前完成的任务,例如预热缓存、校验外部依赖、初始化本地数据,可以放在CommandLineRunner或ApplicationRunner,时机明确,失败时也能直接中断启动,便于在部署侧做回滚与告警。

 

  5、观测启动阶段耗时要选可量化的启动跟踪点

 

  如果你的目标是定位到底哪一步慢,不要只看最后的启动总耗时,可以引入启动跟踪与阶段划分思路,把关键阶段的耗时拆开,再针对性优化扫描范围、条件评估、初始化逻辑与外部依赖调用路径。

 

  6、排查自动配置不生效要沿着条件判断去定位

 

  遇到某个自动配置没生效,不要先猜版本问题,先确认条件注解对应的依赖是否在类路径上,属性开关是否满足,是否被已有Bean抢占,再检查配置加载顺序与Environment取值是否符合预期,这条排查链路通常能把问题收敛到一两个条件点。

  总结

 

  Spring Boot启动流程的主干是SpringApplication.run负责编排,ApplicationContext.refresh负责初始化容器,自动配置负责把依赖与环境转换成可条件生效的配置。把日志现象映射到启动阶段,再把定制需求落到合适的扩展点,你不仅能讲清Spring Boot的启动原理,也能在启动慢、配置不生效、容器行为异常时快速定位到具体阶段与具体机制。

读者也访问过这里:
180 1563 6924