SpringBoot 启动流程
SpringBoot 启动流程
文字流程图
【启动入口】→ 执行标注@SpringBootApplication的主类main方法 ↓├→ 调用SpringApplication.run(主类.class, 命令行参数) ↓
【阶段一:SpringApplication实例化】├→ 1. 推断应用类型(Web/Servlet/WebFlux 或 非Web)├→ 2. 从META-INF/spring.factories加载ApplicationContextInitializer(上下文初始化器)├→ 3. 从META-INF/spring.factories加载ApplicationListener(事件监听器)├→ 4. 推断包含main方法的主类(确保后续注册为核心配置类)↓
【阶段二:执行SpringApplication.run()核心流程】├→ 步骤1:发布ApplicationStartingEvent(应用开始启动事件,用于早期扩展)↓├→ 步骤2:准备Environment(环境配置)│ ├→ 创建对应应用类型的Environment实例(如StandardServletEnvironment)│ ├→ 加载配置源:系统变量→系统属性→命令行参数→application.properties/yaml│ ├→ 激活指定Profiles(如dev/prod,加载对应环境配置)│ └→ 发布ApplicationEnvironmentPreparedEvent(环境就绪事件)↓├→ 步骤3:创建ApplicationContext(IoC容器)│ ├→ Web应用:创建AnnotationConfigServletWebServerApplicationContext│ └→ 非Web应用:创建AnnotationConfigApplicationContext↓├→ 步骤4:上下文预处理│ ├→ 调用ApplicationContextInitializer对上下文进行配置(如注入Environment)│ └→ 发布ApplicationContextInitializedEvent(上下文初始化事件)↓├→ 步骤5:将主类注册为上下文的核心配置类(确保后续扫描与解析)↓├→ 步骤6:刷新ApplicationContext(IoC容器初始化核心步骤)│ ├→ 1. 初始化BeanFactory(创建DefaultListableBeanFactory,Bean管理引擎)│ ├→ 2. 执行BeanFactory后置处理器│ │ ├→ ConfigurationClassPostProcessor解析@ComponentScan,扫描组件并注册Bean定义│ │ └→ 解析@EnableAutoConfiguration,加载META-INF/spring.factories中的AutoConfiguration类│ ├→ 3. 自动配置生效:AutoConfiguration类通过@Conditional判断是否配置Bean(如数据源、Tomcat)│ ├→ 4. 注册Bean后置处理器(用于Bean增强,如AOP代理)│ ├→ 5. 初始化消息源(处理国际化资源)与事件多播器(管理事件发布)│ ├→ 6. Web应用专属:创建并启动嵌入式服务器(如Tomcat,绑定端口)│ ├→ 7. 实例化非懒加载单例Bean(执行构造方法、@PostConstruct,完成依赖注入)│ └→ 8. 发布ContextRefreshedEvent(上下文刷新完成事件)↓
【阶段三:应用就绪收尾】├→ 步骤1:发布ApplicationStartedEvent(应用启动完成事件)├→ 步骤2:执行CommandLineRunner/ApplicationRunner(开发者自定义启动后逻辑,如数据预热)├→ 步骤3:发布ApplicationReadyEvent(应用就绪事件,可处理外部请求)↓
【启动完成】→ 嵌入式服务器监听端口,应用等待接收请求
核心概念
在深入流程前,需明确以下关键组件的作用:
-
@SpringBootApplication
:启动类核心注解,整合@Configuration
(配置类标识)、@ComponentScan
(组件扫描)、@EnableAutoConfiguration
(自动配置开关)三大功能。 -
SpringApplication
:启动流程的 “总指挥”,负责统筹实例化、环境准备、上下文创建等核心步骤。 -
ApplicationContext
:Spring IoC 容器(应用上下文),管理 Bean 的生命周期,不同应用类型(Web / 非 Web)对应不同实现类。 -
Environment
:环境配置容器,存储系统变量、配置文件、命令行参数等配置信息。 -
ApplicationListener
:事件监听器,监听启动过程中的各类事件(如启动开始、环境就绪),实现流程扩展。 -
AutoConfiguration
:自动配置类,通过META-INF/spring.factories
加载,结合@Conditional
注解按需配置 Bean(如数据源、嵌入式服务器)。
各阶段核心细节说明
1. 阶段一:SpringApplication 实例化
此阶段为后续启动 “搭框架”,关键是确定应用类型与加载扩展组件:
-
应用类型推断:通过判断类路径中是否存在
javax.servlet.Servlet
(Servlet Web)、org.springframework.web.reactive.DispatcherHandler
(WebFlux)来区分应用类型,后续创建对应上下文。 -
扩展组件加载:
META-INF/spring.factories
是 SpringBoot 的 “扩展配置文件”,此处加载的初始化器与监听器,将在后续流程中参与上下文配置与事件响应。
2. 阶段二:run () 核心流程(启动核心驱动)
(1)环境准备(Environment)
环境是配置的 “统一容器”,加载顺序决定配置优先级(后加载的配置会覆盖前加载的):
-
优先级从高到低:命令行参数(
--server.port=8081
)> 系统环境变量 > 应用配置文件(application.yaml
)> 系统属性(System.getProperties()
)。 -
多环境配置:通过
spring.profiles.active=dev
激活application-dev.yaml
,实现 “一套代码,多环境部署”。
(2)上下文刷新(refresh ())
此步骤是 Spring IoC 容器初始化的 “核心引擎”,也是自动配置的 “落地环节”:
-
自动配置逻辑:
@EnableAutoConfiguration
导入AutoConfigurationImportSelector
,从META-INF/spring.factories
中加载所有AutoConfiguration
类(如DataSourceAutoConfiguration
),再通过@Conditional
注解(如@ConditionalOnMissingBean
:当容器中没有该 Bean 时才配置)判断是否生效,最终实现 “按需配置”。 -
嵌入式服务器启动:Web 应用中,
TomcatServletWebServerFactory
会创建 Tomcat 实例,设置端口(默认 8080)、上下文路径,最后调用tomcat.start()
启动服务器,无需手动部署 WAR 包。
3. 阶段三:应用就绪收尾
此阶段确保应用 “能干活”,关键是执行自定义逻辑与通知就绪状态:
-
CommandLineRunner vs ApplicationRunner:两者功能类似,区别在于参数类型 —— 前者接收
String[]
原始命令行参数,后者接收ApplicationArguments
(支持解析--key=value
格式参数)。 -
事件触发顺序:启动过程中事件按 “
Starting
→EnvironmentPrepared
→ContextRefreshed
→Started
→Ready
” 顺序触发,开发者可通过@EventListener
监听指定事件,实现扩展(如监听ApplicationReadyEvent
打印启动成功日志)。
常见问题与扩展点
1. 常见启动问题排查
-
Bean 未注册:检查
@ComponentScan
扫描范围是否覆盖 Bean 所在包(默认扫描主类所在包及其子包),或是否遗漏@Component
/@Service
等注解。 -
端口冲突:通过
netstat -ano | findstr "8080"
(Windows)/lsof -i:8080
(Linux)查看占用端口的进程,或修改server.port=0
(随机端口)。 -
自动配置不生效:添加
debug=true
到配置文件,启动日志会打印 “自动配置生效 / 不生效” 的原因(如缺少依赖导致@ConditionalOnClass
不满足)。
2. 核心扩展点(开发者自定义)
-
自定义初始化器:实现
ApplicationContextInitializer
,重写initialize
方法(如设置全局配置context.getEnvironment().setActiveProfiles("dev")
),并在META-INF/spring.factories
中注册。 -
自定义监听器:实现
ApplicationListener<ApplicationReadyEvent>
,监听应用就绪事件,执行启动后通知(如发送启动成功消息到消息队列)。 -
自定义自动配置:创建
XXXAutoConfiguration
类,通过@Conditional
定义生效条件,在META-INF/spring.factories
中添加org.springframework.boot.autoconfigure.EnableAutoConfiguration=``com.xxx``.XXXAutoConfiguration
,实现 “自定义组件开箱即用”。