Spring 项目启动流程详解

以 Spring Boot 为基础,涵盖 Spring Framework 核心机制。梳理从 main() 到应用完全就绪的完整生命周期,包括各阶段事件、回调时机和扩展点。


目录


1. 整体流程概览

启动入口
  → SpringApplication 初始化
  → Environment 准备
  → Banner 打印
  → ApplicationContext 创建
  → ApplicationContext 准备(Pre-Refresh)
  → ApplicationContext 刷新(Refresh)★ 最核心
  → ApplicationContext 后处理(Post-Refresh)
  → Runner 执行
  → 启动完成回调

2. 阶段 1:SpringApplication 构造

SpringApplication.run(MyApp.class, args);

执行 new SpringApplication(primarySources) 时:

步骤说明相关 API
推断应用类型根据 classpath 判断:SERVLET(Spring MVC)、REACTIVE(WebFlux)或 NONE(普通应用)WebApplicationType.deduceFromClasspath()
加载 ApplicationContextInitializer从 META-INF/spring.factories 中读取SpringFactoriesLoader
加载 ApplicationListener从 META-INF/spring.factories 中读取SpringFactoriesLoader
推断主类通过 RuntimeException().getStackTrace() 推断 main 方法所在类deduceMainApplicationClass()

应用类型推断逻辑

classpath 包含 DispatcherServlet 且不含 Reactive → SERVLET
classpath 包含 Reactive 相关类 → REACTIVE
否则 → NONE

3. 阶段 2:run() 方法执行——启动前准备

public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();          // 1. 启动计时
    stopWatch.start();

    DefaultBootstrapContext bootstrapContext = createBootstrapContext();  // 2. 创建引导上下文

    configureHeadlessProperty();                     // 3. 设置 java.awt.headless

    SpringApplicationRunListeners listeners = getRunListeners(args);  // 4. 获取 RunListeners

    // ... 后续步骤
}

3.1 SpringApplicationRunListener

Spring Boot 特有的监听机制,比 Spring 自身的 ApplicationEvent 更早介入,贯穿整个启动过程:

回调方法触发时机此时 Context 状态
starting()启动最开始,任何处理之前无
environmentPrepared()Environment 创建完毕Context 尚未创建
contextPrepared()ApplicationContext 创建完毕尚未 refresh
contextLoaded()Bean 定义全部加载完毕refresh 之前
started()refresh 完成Runner 执行前
ready()所有启动完成应用真正就绪
failed()启动过程中异常—

注意:SpringApplicationRunListener 需要通过 META-INF/spring.factories 注册(Spring Boot 2.x)或通过 META-INF/spring/org.springframework.boot.SpringApplicationRunListener 注册(Spring Boot 3.x)。


4. 阶段 3:Environment 准备

ConfigurableEnvironment environment =
    prepareEnvironment(listeners, bootstrapContext, args);

执行顺序

  1. 创建 ConfigurableEnvironment
    • Servlet 应用 → StandardServletEnvironment
    • Reactive 应用 → StandardReactiveWebEnvironment
  2. 配置 PropertySources:
    • 命令行参数(--server.port=8080)
    • 系统属性(System.getProperties())
    • 环境变量(System.getenv())
    • application.properties / application.yml(后续加载)
  3. 激活 Profile(spring.profiles.active)
  4. 执行所有 EnvironmentPostProcessor
  5. 触发 ApplicationEnvironmentPreparedEvent

事件

事件说明
ApplicationEnvironmentPreparedEventEnvironment 准备完毕,PropertySources 已就绪

5. 阶段 4:创建并准备 ApplicationContext

Banner printedBanner = printBanner(environment);     // 6. 打印 Banner

ConfigurableApplicationContext context = createApplicationContext();  // 7. 创建 Context

prepareContext(bootstrapContext, context, environment, listeners, args);  // 8. 准备 Context

Context 类型对应

WebApplicationTypeContext 类型
SERVLETAnnotationConfigServletWebServerApplicationContext
REACTIVEAnnotationConfigReactiveWebServerApplicationContext
NONEAnnotationConfigApplicationContext

prepareContext 内部执行步骤

  1. 设置 Environment 到 Context
  2. 执行 所有 ApplicationContextInitializer 的 initialize() 方法
  3. 注册主类为 Bean 定义
  4. 加载 sources(主类上的 @ComponentScan、@Import、@Bean 等配置)
  5. 触发 ApplicationContextInitializedEvent

事件

事件说明
ApplicationContextInitializedEventContext 已初始化,Bean 定义加载完毕,但尚未 refresh

6. 阶段 5:Refresh——ApplicationContext 刷新(最核心)

refreshContext(context);

AbstractApplicationContext.refresh() 是 Spring Framework 的绝对核心,所有 Bean 的创建、注入、代理都在此阶段完成。

6.1 refresh() 十二步详解

步骤方法说明触发事件
①prepareRefresh()设置启动时间、激活标志、初始化 PropertySources、校验 required properties—
②obtainFreshBeanFactory()获取 BeanFactory(Spring Boot 中通常是 DefaultListableBeanFactory)—
③prepareBeanFactory()设置 ClassLoader、SPEL 解析器、注册默认 Bean(Environment、ApplicationContext 等)—
④postProcessBeanFactory()BeanFactory 后处理:留给子类扩展。如 Web 应用注册 Request/Session scope—
⑤invokeBeanFactoryPostProcessors()执行 BeanFactoryPostProcessor:最关键的 ConfigurationClassPostProcessor 在此解析 @Configuration、@ComponentScan、@Import、@Bean—
⑥registerBeanPostProcessors()注册 BeanPostProcessor 到 BeanFactory(此时仅注册,后续 Bean 创建时才执行)—
⑦initMessageSource()初始化国际化资源 MessageSource—
⑧initApplicationEventMulticaster()初始化事件广播器 ApplicationEventMulticaster—
⑨onRefresh()留给子类:Spring Boot 在此启动内嵌 Web 服务器(Tomcat / Jetty / Netty)WebServerInitializedEvent
⑩registerListeners()注册所有 ApplicationListener 到广播器,广播早期事件(early application events)—
⑪finishBeanFactoryInitialization()实例化所有非懒加载的单例 Bean(依赖注入、@PostConstruct、InitializingBean) ★—
⑫finishRefresh()清除缓存、初始化 LifecycleProcessor、发布 ContextRefreshedEventContextRefreshedEvent

6.2 步骤 ⑪ 深入:Bean 的生命周期

在 finishBeanFactoryInitialization() 阶段,每个非懒加载的单例 Bean 依次经历:

getBean(name)
  │
  └─ createBean()
       │
       ├─ resolveBeforeInstantiation()
       │     (InstantiationAwareBeanPostProcessor 有机会返回代理,跳过后续步骤)
       │
       └─ doCreateBean()
            │
            ├─ createBeanInstance()
            │     构造器/工厂方法实例化
            │
            ├─ applyMergedBeanDefinitionPostProcessors()
            │     MergedBeanDefinitionPostProcessor 处理 @Autowired、@Value 等元数据
            │
            ├─ populateBean()
            │   ├─ InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
            │   ├─ InstantiationAwareBeanPostProcessor.postProcessProperties()
            │   │     (@Autowired、@Resource 等在此处理)
            │   └─ applyPropertyValues()
            │
            └─ initializeBean()
                 ├─ invokeAwareMethods()
                 │     BeanNameAware → BeanClassLoaderAware → BeanFactoryAware
                 │
                 ├─ applyBeanPostProcessorsBeforeInitialization()
                 │     (@PostConstruct 在此执行,由 CommonAnnotationBeanPostProcessor 处理)
                 │
                 ├─ invokeInitMethods()
                 │   ├─ InitializingBean.afterPropertiesSet()
                 │   └─ @Bean(initMethod) 指定的方法
                 │
                 └─ applyBeanPostProcessorsAfterInitialization()
                       (AOP 代理在此生成,由 AbstractAutoProxyCreator 处理)
Bean 生命周期回调顺序(完整)
1.  BeanFactoryPostProcessor.postProcessBeanFactory()
2.  InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
3.  构造器实例化
4.  MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()
5.  InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
6.  InstantiationAwareBeanPostProcessor.postProcessProperties()
7.  BeanNameAware.setBeanName()
8.  BeanClassLoaderAware.setBeanClassLoader()
9.  BeanFactoryAware.setBeanFactory()
10. EnvironmentAware / ApplicationContextAware / ... 等各类 Aware
11. BeanPostProcessor.postProcessBeforeInitialization()
12. @PostConstruct 方法
13. InitializingBean.afterPropertiesSet()
14. @Bean(initMethod) 方法
15. BeanPostProcessor.postProcessAfterInitialization()  ← AOP 代理生成
    ─── Bean 就绪 ───
16. @PreDestroy 方法
17. DisposableBean.destroy()
18. @Bean(destroyMethod) 方法

7. 阶段 6~8:启动后处理 → Runner → 就绪

阶段 6:启动后处理

afterRefresh(context, args);   // 默认为空,留给子类扩展

stopWatch.stop();              // 停止计时

listeners.started(context);    // ★ 发布 ApplicationStartedEvent

阶段 7:执行 Runner

callRunners(context, applicationArguments);

执行顺序(同一类型内按 @Order / @Priority 排序):

  1. ApplicationRunner(接收解析后的 ApplicationArguments)
  2. CommandLineRunner(接收原始 String... args)

阶段 8:应用就绪

listeners.ready(context);      // ★ 发布 ApplicationReadyEvent

8. 完整事件时间线

┌──────────────────────────────────────────────────┐
│             SpringApplication.run() 开始            │
└──────────────────────────────────────────────────┘
                      │
                      ▼
          ┌──────────────────────┐
          │  StartingEvent       │  ← Spring Boot 启动事件
          │  (ApplicationStartingEvent)
          └──────────────────────┘
                      │
                      ▼
          ┌──────────────────────┐
          │  Environment 准备      │
          │  ├─ EnvironmentPostProcessor │
          │  └─ ApplicationEnvironmentPreparedEvent │
          └──────────────────────┘
                      │
                      ▼
          ┌──────────────────────┐
          │  Context 创建并初始化   │
          │  ├─ ApplicationContextInitializer │
          │  └─ ApplicationContextInitializedEvent │
          └──────────────────────┘
                      │
                      ▼
          ┌──────────────────────┐
          │  加载 Bean 定义       │
          │  └─ ApplicationPreparedEvent │
          │    (Context 尚未 refresh)  │
          └──────────────────────┘
                      │
                      ▼
   ╔══════════════════════════════════════╗
   ║     refresh()  ——  核心流程         ║
   ╠══════════════════════════════════════╣
   ║  ① prepareRefresh                   ║
   ║  ② obtainFreshBeanFactory           ║
   ║  ③ prepareBeanFactory               ║
   ║  ④ postProcessBeanFactory           ║
   ║  ⑤ BeanFactoryPostProcessor 执行      ║
   ║  ⑥ BeanPostProcessor 注册           ║
   ║  ⑦ initMessageSource                ║
   ║  ⑧ initApplicationEventMulticaster  ║
   ║  ⑨ onRefresh — WebServer 启动       ║
   ║  ⑩ registerListeners                ║
   ║  ⑪ 所有单例 Bean 实例化 ★            ║
   ║  ⑫ ContextRefreshedEvent ★          ║
   ╚══════════════════════════════════════╝
                      │
                      ▼
          ┌──────────────────────┐
          │  ApplicationStartedEvent │  ← Spring Boot(refresh 后,Runner 前)
          └──────────────────────┘
                      │
                      ▼
          ┌──────────────────────┐
          │  ApplicationRunner   │
          │  CommandLineRunner   │
          └──────────────────────┘
                      │
                      ▼
          ┌──────────────────────┐
          │  ApplicationReadyEvent │  ← 应用完全就绪 ★
          └──────────────────────┘

9. 事件分类对照表

Spring Boot 特有事件

事件时机用途示例
ApplicationStartingEvent启动最开始记录启动日志、初始化监控
ApplicationEnvironmentPreparedEventEnvironment 就绪动态修改配置、加载加密配置
ApplicationContextInitializedEventContext 初始化后(refresh 前)注册额外 Bean 定义
ApplicationPreparedEventBean 定义加载完毕(refresh 前)修改 Bean 定义
ApplicationStartedEventrefresh 完成后,Runner 前执行需要在 Runner 之前完成的操作
ApplicationReadyEvent完全就绪发送"应用已启动"通知、预热完成
ApplicationFailedEvent启动失败记录失败信息、发送告警

Spring Framework 标准事件

事件时机
ContextRefreshedEventApplicationContext refresh 完成(或重新 refresh)
ContextStartedEventApplicationContext start(ConfigurableApplicationContext.start())
ContextStoppedEventApplicationContext stop
ContextClosedEventApplicationContext 关闭

Spring Boot Web 事件

事件说明
WebServerInitializedEventWeb 服务器初始化完成,可获取端口号
ServletWebServerInitializedEventServlet Web 服务器就绪(子类)
ReactiveWebServerInitializedEventReactive Web 服务器就绪(子类)

10. 常用扩展点速查

想做什么使用哪个扩展点注册方式
在所有 Bean 创建前修改 Bean 定义BeanFactoryPostProcessor@Component / @Bean
在某个 Bean 初始化前后做处理BeanPostProcessor@Component / @Bean
动态修改环境配置(解密、追加)EnvironmentPostProcessorspring.factories
加载额外的配置源PropertySourceLoaderspring.factories
在所有 Bean 初始化后执行一次性逻辑ApplicationListener<ContextRefreshedEvent>@Component / @EventListener
启动后执行初始化任务(查数据库、预热缓存)CommandLineRunner / ApplicationRunner,配合 @Order@Component
应用真正就绪后执行ApplicationListener<ApplicationReadyEvent>@Component / @EventListener
获取 Web 服务端口ApplicationListener<WebServerInitializedEvent>@Component / @EventListener
优雅关闭时清理资源@PreDestroy / DisposableBean / ApplicationListener<ContextClosedEvent>@Bean / @Component
提前干预整个启动流程SpringApplicationRunListenerspring.factories
ApplicationContext 创建后定制ApplicationContextInitializerspring.factories
自定义 FailureAnalyzer 分析启动失败FailureAnalyzerspring.factories

代码示例

ApplicationRunner(推荐,可获取解析后的参数)
@Component
@Order(1)
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) {
        // args.getOptionNames()  →  解析后的 key
        // args.getOptionValues("name")  →  值列表
        // args.getNonOptionArgs()  →  非选项参数
    }
}
事件监听(注解方式)
@Component
public class MyEventListener {

    @EventListener
    public void onReady(ApplicationReadyEvent event) {
        // 应用完全就绪
    }

    @EventListener
    public void onRefresh(ContextRefreshedEvent event) {
        // Context 刷新完成
    }

    @EventListener
    public void onWebServer(WebServerInitializedEvent event) {
        int port = event.getWebServer().getPort();
    }
}
Aware 接口获取框架对象
@Component
public class MyComponent implements ApplicationContextAware, EnvironmentAware {

    @Override
    public void setApplicationContext(ApplicationContext ctx) {
        // 获取 ApplicationContext
    }

    @Override
    public void setEnvironment(Environment env) {
        // 获取 Environment
    }
}

11. 启动异常处理

启动过程中任何阶段抛出异常都会触发:

catch (Throwable ex) {
    handleRunFailure(context, ex, listeners);
    throw new IllegalStateException(ex);
}
  1. 发布 ApplicationFailedEvent
  2. Spring Boot 会尝试通过 FailureAnalyzer 分析异常并给出人类可读的诊断
  3. 调用 SpringApplicationRunListener.failed()
  4. 如果 Context 已创建,调用 close() 释放资源

12. 关键源码入口

类路径说明
SpringApplicationorg.springframework.boot启动入口
AbstractApplicationContextorg.springframework.context.supportrefresh() 方法所在地
DefaultListableBeanFactoryorg.springframework.beans.factory.support默认 BeanFactory 实现
ConfigurationClassPostProcessororg.springframework.context.annotation解析 @Configuration 的核心处理器
AbstractAutowireCapableBeanFactoryorg.springframework.beans.factory.supportBean 生命周期 doCreateBean() 所在地
AutowiredAnnotationBeanPostProcessororg.springframework.beans.factory.annotation处理 @Autowired
CommonAnnotationBeanPostProcessororg.springframework.context.annotation处理 @PostConstruct / @PreDestroy
AbstractAutoProxyCreatororg.springframework.aop.framework.autoproxyAOP 代理创建
ServletWebServerApplicationContextorg.springframework.boot.web.servlet.contextWeb 服务器启动(onRefresh)

最后更新:2026-06-16

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐