---
url: /java/spring-boot-startup.md
---
# Spring Boot 启动流程深度解析

## 目录

1. [概述](#概述)
2. [入口方法 SpringApplication.run()](#入口方法-springapplicationrun)
3. [SpringApplication 构造函数初始化](#springapplication-构造函数初始化)
4. [run() 方法核心流程](#run-方法核心流程)
5. [启动器监听器 (ApplicationListener)](#启动器监听器-applicationlistener)
6. [环境准备 (Environment Preparation)](#环境准备-environment-preparation)
7. [配置数据加载机制 (ConfigData Loading)](#配置数据加载机制-configdata-loading)
8. [ApplicationContext 创建与初始化](#applicationcontext-创建与初始化)
9. [自动配置 (Auto-Configuration)](#自动配置-auto-configuration)
10. [上下文刷新 (Context Refresh)](#上下文刷新-context-refresh)
11. [Bean 生命周期](#bean-生命周期)
12. [Web 容器启动](#web-容器启动)
13. [启动完成回调](#启动完成回调)
14. [应用事件生命周期](#应用事件生命周期)
15. [优雅关闭 (Graceful Shutdown)](#优雅关闭-graceful-shutdown)
16. [一句话总结](#一句话总结)

***

## 概述

Spring Boot 的启动流程是一个精心设计的多阶段过程，从 JVM 启动到应用程序完全就绪，涉及多个关键组件的协同工作。整个流程以 `SpringApplication` 类为核心，通过一系列有序的步骤完成应用的引导（Bootstrap）。

### 核心组件

| 组件 | 职责 |
|------|------|
| `SpringApplication` | 启动流程的核心入口，协调所有启动步骤 |
| `SpringApplicationRunListeners` | 管理启动过程中的事件监听器 |
| `ConfigurableEnvironment` | 管理应用的环境配置和属性源 |
| `ConfigurableApplicationContext` | Spring 应用上下文，负责 Bean 的管理 |
| `AutoConfigurationImportSelector` | 自动配置类的选择和导入 |
| `Embedded Web Server` | 内嵌 Web 服务器（Tomcat/Jetty/Undertow） |

***

## 入口方法 SpringApplication.run()

### 静态便捷方法

```java
@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}
```

`SpringApplication.run()` 是一个静态辅助方法，其内部执行流程：

```java
public static ConfigurableApplicationContext run(Class<?> primarySource, String[] args) {
    return run(new SpringApplication(primarySource), args);
}
```

### @SpringBootApplication 注解分解

该组合注解等价于：

```java
@SpringBootConfiguration      // @Configuration，标记为配置类
@EnableAutoConfiguration     // 启用自动配置
@ComponentScan              // 组件扫描
public @interface SpringBootApplication {
    // ...
}
```

***

## SpringApplication 构造函数初始化

当创建 `SpringApplication` 实例时，会执行以下初始化操作：

```java
public SpringApplication(Class<?>... primarySources) {
    this(null, primarySources);
}

public SpringApplication(@Nullable ResourceLoader resourceLoader, Class<?>... primarySources) {
    Assert.notEmpty(primarySources, "At least one primary source must be specified");
    
    // 1. 确定主配置类
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    
    // 2. 推断应用类型（标准/Servlet/反应式/WebFlux）
    this.applicationMode = deduceApplicationMode();
    
    // 3. 推断并设置 ClassLoader
    this.classLoader = Thread.currentThread().getContextClassLoader();
    
    // 4. 初始化主要监听器
    setInitializers((Collection) Collections.emptyList());
    setListeners(Collections.emptyList());
    
    // 5. 推断 Main 方法所在类
    this.mainApplicationClass = deduceMainApplicationClass();
    
    // 6. 设置默认 banner
    this.banner = (Banner) new ConsoleBanner();
    this.bannerMode = Banner.Mode.CONSOLE;
    
    // 7. 设置日志系统
    this.logFileName = null;
}
```

### 应用类型推断

```java
private ApplicationMode deduceApplicationMode() {
    if (isWebApplication()) {
        if (isReactiveWebApplication()) {
            return ApplicationMode.REACTIVE_WEB;
        }
        return ApplicationMode.SERVLET;
    }
    return ApplicationMode.NONE;
}
```

***

## run() 方法核心流程

这是整个启动流程的核心方法，包含完整的启动步骤：

```java
public ConfigurableApplicationContext run(String... args) {
    // ==================== 步骤 1: 创建启动监听器 ====================
    long startTime = System.nanoTime();
    SpringApplicationRunListeners listeners = getRunListeners(args);
    
    // ==================== 步骤 2: 发布启动开始事件 ====================
    listeners.starting();
    
    // ==================== 步骤 3: 准备 Environment ====================
    ConfigurableEnvironment environment = prepareEnvironment(listeners, args);
    
    // ==================== 步骤 4: 打印 Banner ====================
    if (this.bannerMode != Mode.OFF) {
        printBanner(environment);
    }
    
    // ==================== 步骤 5: 创建 ApplicationContext ====================
    ConfigurableApplicationContext context = createApplicationContext();
    
    // ==================== 步骤 6: 准备 ApplicationContext ====================
    prepareContext(context, environment, listeners, args);
    
    // ==================== 步骤 7: 刷新上下文 ====================
    refreshContext(context);
    
    // ==================== 步骤 8: 刷新后处理 ====================
    afterRefresh(context, args);
    
    // ==================== 步骤 9: 发布启动完成事件 ====================
    listeners.started(context);
    
    try {
        // ==================== 步骤 10: 执行 CommandLineRunner/ApplicationRunner ====================
        callRunners(context, args);
    }
    catch (Throwable ex) {
        throw new IllegalStateException(ex);
    }
    
    // ==================== 步骤 11: 发布就绪事件 ====================
    listeners.ready(context);
    
    // 记录启动时间
    Duration timeTaken = Duration.ofNanos(System.nanoTime() - startTime);
    
    return context;
}
```

***

## 启动器监听器 (ApplicationListener)

### SpringApplicationRunListeners

```java
private SpringApplicationRunListeners getRunListeners(String[] args) {
    Set<Class<? extends ApplicationListener<?>>> listenerClasses = getSpringFactoriesInstances(
        ApplicationListener.class);
    
    // 按顺序排序监听器
    List<ApplicationListener<?>> listeners = new ArrayList<>();
    for (Class<? extends ApplicationListener<?>> listenerClass : listenerClasses) {
        listeners.add(instantiate(listenerClass, args, this));
    }
    
    return new SpringApplicationRunListeners(this, listeners);
}
```

### 关键内置监听器

| 监听器 | 职责 |
|--------|------|
| `LoggingApplicationListener` | 初始化日志系统，最早执行的监听器 |
| `ConfigDataListeners` | 配置数据加载监听 |
| `LiveReloadServerApplicationListener` | 热重载支持 |
| `EventPublishingRunListener` | 事件发布的包装器 |

### LoggingApplicationListener

作为第一个被调用的监听器，它负责在环境完全初始化之前设置基本的日志能力：

```java
@Override
public void onApplicationStartingEvent(ApplicationStartingEvent event) {
    initialize(event.getBootstrapContext(), 
               event.getArgs(), 
               SpringApplication.class.getClassLoader());
}

private void initialize(ConfigurableBootstrapContext bootstrapContext,
                       String[] args, 
                       ClassLoader classLoader) {
    // 1. 创建临时环境用于日志配置
    ConfigurableEnvironment environment = new StandardEnvironment();
    configureEnvironment(args, environment);
    
    // 2. 获取日志系统实现（Logback/Log4j2等）
    LoggingSystem loggingSystem = LoggingSystemFactory.getLoggingSystem(classLoader);
    
    // 3. 初始化日志系统
    loggingSystem.initialize(getInitializationContext(environment),
                            getLoggingConfigLocation(environment),
                            LogFile.get(environment.getPropertyResolver()));
}
```

***

## 环境准备 (Environment Preparation)

### prepareEnvironment() 方法

```java
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
                                                   String[] args) {
    // 1. 创建可配置环境
    ConfigurableEnvironment environment = getOrCreateEnvironment();
    
    // 2. 配置环境（设置 PropertySources）
    configureEnvironment(args, environment);
    
    // 3. 发布环境准备事件
    listeners.environmentPrepared(environment);
    
    // 4. 重新绑定主类（处理 Profile 相关逻辑）
    bindToSpringApplication(environment);
    
    return environment;
}
```

### EnvironmentPostProcessor

在环境准备完成后，会执行所有注册的 `EnvironmentPostProcessor`：

```java
// 从 META-INF/spring.factories 加载
Set<Class<? extends EnvironmentPostProcessor>> processors = 
    getSpringFactoriesInstances(EnvironmentPostProcessor.class);

for (EnvironmentPostProcessor processor : processors) {
    processor.postProcessEnvironment(environment, application);
}
```

### 重要 EnvironmentPostProcessor

| Processor | 功能 |
|-----------|------|
| `ConfigDataEnvironmentPostProcessor` | 加载配置数据（Spring Boot 2.4+） |
| `SharedEntityManagerBeanEnvironmentPostProcessor` | JPA 配置处理 |
| `BindingValidationEnvironmentPostProcessor` | 绑定验证 |
| `SpringBootEnvCommandlineArgsProcessor` | 命令行参数处理 |

***

## 配置数据加载机制 (ConfigData Loading)

### ConfigData 新架构（Spring Boot 2.4+）

Spring Boot 2.4 引入了全新的配置加载机制，取代了原来的 bootstrap.jar 方式。

### ConfigDataEnvironmentPostProcessor

```java
public void postProcessEnvironment(ConfigurableEnvironment environment,
                                   SpringApplication application) {
    // 使用 ConfigData 机制加载配置
    applyTo(environment, null, null, Collections.emptyList());
}
```

### 配置加载优先级顺序

```
1. 命令行参数 (Command Line Arguments)
2. 来自 java:comp/env 的 JNDI 属性
3. Java 系统属性 (System.getProperties())
4. 操作系统环境变量
5. 随机属性值 (random.* 属性)
6. jar 包外部的 application-{profile}.properties/yml
7. jar 包内部的 application-{profile}.properties/yml
8. jar 包外部的 application.properties/yml
9. jar 包内部的 application.properties/yml
10. @Configuration 类上的 @PropertySource
11. 默认属性 (SpringApplication.setDefaultProperties)
```

### ConfigDataLoader

```java
public interface ConfigDataLoader<R extends ConfigDataResource> {
    // 判断资源是否可加载
    default boolean isLoadable(ConfigDataLoaderContext context, R resource) {
        return true;
    }
    
    // 加载配置数据
    @Nullable
    ConfigData load(ConfigDataLoaderContext context, R resource) 
        throws IOException, ConfigDataResourceNotFoundException;
}
```

### 配置文件位置（由高到低优先级）

```
./config/
./
classpath:/config/
classpath:/
```

***

## ApplicationContext 创建与初始化

### 上下文类型选择

```java
protected ConfigurableApplicationContext createApplicationContext() {
    Class<?> contextClass = this.contextClass;
    
    if (this.applicationMode == ApplicationMode.SERVLET) {
        // Servlet 应用使用 ServletWebServerApplicationContext
        contextClass = ServletWebServerApplicationContext.class;
    }
    else if (this.applicationMode == ApplicationMode.REACTIVE_WEB) {
        // 响应式应用使用 ReactorWebApplicationContext
        contextClass = ReactiveWebServerApplicationContext.class;
    }
    
    if (contextClass == null) {
        // 默认使用 AnnotationConfigApplicationContext
        contextClass = AnnotationConfigApplicationContext.class;
    }
    
    return (ConfigurableApplicationContext) instantiate(contextClass);
}
```

### 上下文初始化器

```java
protected void prepareContext(ConfigurableApplicationContext context,
                             ConfigurableEnvironment environment,
                             SpringApplicationRunListeners listeners,
                             String[] args) {
    // 1. 设置 Environment
    context.setEnvironment(environment);
    
    // 2. 应用 ApplicationContextInitializer
    postProcessApplicationContext(context);
    applyInitializers(context);
    
    // 3. 发布上下文初始化事件
    listeners.contextInitialized(context);
}
```

### ContextIdApplicationContextInitializer

```java
public void initialize(ConfigurableApplicationContext applicationContext) {
    String id = applicationContext.getEnvironment()
        .getProperty("spring.application.name", "application");
    applicationContext.setId(id);
}
```

***

## 自动配置 (Auto-Configuration)

### @EnableAutoConfiguration 原理

```java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    // ...
}
```

### AutoConfigurationImportSelector

这是自动配置的核心类，负责选择和导入符合条件的配置类：

```java
public class AutoConfigurationImportSelector implements DeferredImportSelector {
    
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        // 1. 加载所有自动配置类候选
        List<String> configurations = getCandidateConfigurations(annotationMetadata);
        
        // 2. 应用排除规则
        configurations.removeAll(getExcludes(annotationMetadata));
        
        // 3. 应用过滤规则
        return AutConfigurationImportFilter.filter(configurations);
    }
    
    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata) {
        // 从 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 加载
        return SpringFactoriesLoader.loadFactoryNames(
            this.beanClassLoader, 
            AutoConfiguration.class.getName());
    }
}
```

### 条件注解体系

| 注解 | 说明 |
|------|------|
| `@ConditionalOnClass` | 当指定类在类路径中存在时匹配 |
| `@ConditionalOnMissingClass` | 当指定类不在类路径中时匹配 |
| `@ConditionalOnProperty` | 当指定属性存在且值匹配时匹配 |
| `@ConditionalOnBean` | 当指定 Bean 已注册时匹配 |
| `@ConditionalOnMissingBean` | 当指定 Bean 未注册时匹配（最重要） |
| `@ConditionalOnSingleCandidate` | 当只有一个候选 Bean 时匹配 |
| `@ConditionalOnExpression` | SpEL 表达式结果为 true 时匹配 |
| `@ConditionalOnResource` | 指定资源存在时匹配 |
| `@ConditionalOnWebApplication` | Web 应用时匹配 |
| `@ConditionalOnNotWebApplication` | 非 Web 应用时匹配 |

### 自动配置示例

```java
@Configuration
@ConditionalOnClass(HttpServlet.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnProperty(prefix = "server", name = "port", havingValue = "0", matchIfMissing = true)
@EnableConfigurationProperties(ServerProperties.class)
public class EmbeddedWebServerFactoryCustomizerAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(
            Environment environment,
            ServerProperties serverProperties,
            TomcatServerProperties tomcatProperties) {
        return new TomcatWebServerFactoryCustomizer(environment, 
                                                   serverProperties, 
                                                   tomcatProperties);
    }
}
```

***

## 上下文刷新 (Context Refresh)

这是整个启动过程中最复杂的一步，涉及大量内部操作：

```java
private void refreshContext(ConfigurableApplicationContext context) {
    refresh(context);
}
```

### AbstractApplicationContext.refresh() 详细流程

```java
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // ==================== 步骤 1: 准备刷新 ====================
        prepareRefresh();
        
        // ==================== 步骤 2: 获取 BeanFactory ====================
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        
        // ==================== 步骤 3: 准备 BeanFactory ====================
        prepareBeanFactory(beanFactory);
        
        try {
            // ==================== 步骤 4: 子类扩展点 ====================
            postProcessBeanFactory(beanFactory);
            
            // ==================== 步骤 5: 执行 BeanFactoryPostProcessor ====================
            invokeBeanFactoryPostProcessors(beanFactory);
            
            // ==================== 步骤 6: 注册 BeanPostProcessor ====================
            registerBeanPostProcessors(beanFactory);
            
            // ==================== 步骤 7: 初始化消息源 ====================
            initMessageSource();
            
            // ==================== 步骤 8: 初始化事件广播器 ====================
            initApplicationEventMulticaster();
            
            // ==================== 步骤 9: 初始化子上下文 ====================
            onRefresh();
            
            // ==================== 步骤 10: 注册监听器 ====================
            registerListeners();
            
            // ==================== 步骤 11: 实例化剩余单例 Bean ====================
            finishBeanFactoryInitialization(beanFactory);
            
            // ==================== 步骤 12: 完成刷新 ====================
            finishRefresh();
        }
        catch (BeansException ex) {
            destroyBeans();
            cancelRefresh(ex);
            throw ex;
        }
        finally {
            resetCommonCaches();
        }
    }
}
```

### 关键步骤详解

#### 步骤 1: prepareRefresh()

```java
protected void prepareRefresh() {
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);
    
    // 验证并解析 Environment 中的属性
    getEnvironment().resolveRequiredPlaceholders();
    
    // 添加 StartupStep 用于监控
}
```

#### 步骤 2: obtainFreshBeanFactory()

```java
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    // 刷新 BeanFactory，对于 AnnotationConfig 基于的上下文，
    // 这会触发配置类的处理和 BeanDefinition 的注册
    getBeanFactory().refreshBeanDefinitions();
    return getBeanFactory();
}
```

#### 步骤 3: prepareBeanFactory()

```java
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 设置 ClassLoader
    beanFactory.setClassLoader(getClassLoader());
    
    // 添加 BeanPostProcessor（基础设施相关的）
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    
    // 忽略某些自动依赖
    beanFactory.ignoreDependencyExplicitInterface(
        Environment.class, 
        ResourceLoader.class, 
        ApplicationEventPublisher.class);
    
    // 添加 BeanPostProcessor 检查器
    beanFactory.addBeanPostProcessor(new InstantiationAwareBeanPostProcessorAdapter());
}
```

#### 步骤 5: invokeBeanFactoryPostProcessors()

这是非常关键的步骤，执行所有 `BeanFactoryPostProcessor`：

```java
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 1. 执行 PriorityOrdered 的 BFP
    invokeBeanFactoryPostProcessors(beanFactory, 
        beanFactory.getBeanPostProcessors(PriorityOrdered.class));
    
    // 2. 执行 Ordered 的 BFP
    invokeBeanFactoryPostProcessors(beanFactory, 
        beanFactory.getBeanPostProcessors(Ordered.class));
    
    // 3. 执行剩余的 BFP
    String[] names = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, 
                                                     false, false);
    for (String name : names) {
        if (!processed.contains(name)) {
            BeanFactoryPostProcessor bfp = beanFactory.getBean(name, BeanFactoryPostProcessor.class);
            bfp.postProcessBeanFactory(beanFactory);
        }
    }
    
    // 4. 执行 ConfigurationClassPostProcessor（处理@Configuration类）
    // 5. 执行 PropertySourcesPlaceholderConfigurer（占位符解析）
}
```

#### 步骤 6: registerBeanPostProcessors()

```java
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    String[] names = beanFactory.getBeanNamesForType(BeanPostProcessor.class, false, false);
    
    for (String name : names) {
        Object bp = beanFactory.getBean(name);
        if (bp instanceof BeanPostProcessor) {
            beanFactory.addBeanPostProcessor((BeanPostProcessor) bp);
        }
    }
}
```

### 重要的 BeanPostProcessor

| PostProcessor | 职责 |
|---------------|------|
| `ConfigurationClassPostProcessor` | 处理 @Configuration 类 |
| `AutowiredAnnotationBeanPostProcessor` | 处理 @Autowired 注入 |
| `CommonAnnotationBeanPostProcessor` | 处理 @PostConstruct/@PreDestroy |
| `ConfigurationPropertiesBindingPostProcessor` | 绑定 @ConfigurationProperties |
| `ScopedProxyProcessor` | 处理作用域代理 |

#### ConfigurationClassPostProcessor

```java
public class ConfigurationClassPostProcessor implements BeanFactoryPostProcessor {
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 解析所有@Configuration类及其@Import、@ComponentScan等注解
        ConfigurationClassParser parser = new ConfigurationClassParser(metadataReader);
        parser.parse(this.configurationClasses);
        
        // 将解析结果转换为 BeanDefinition 并注册
        ConfigurationClassBeanDefinitionReader reader = 
            new ConfigurationClassBeanDefinitionReader(beanFactory, parser.getConfigurationClasses());
        reader.loadBeanDefinitions();
    }
}
```

#### 配置类解析过程

```
1. 读取主配置类 (@SpringBootApplication)
2. 解析 @ComponentScan -> 发现组件并注册为 BeanDefinition
3. 解析 @EnableAutoConfiguration -> 导入 AutoConfigurationImportSelector
4. AutoConfigurationImportSelector.selectImports() -> 加载所有自动配置类
5. 应用 @Conditional 条件过滤
6. 解析每个配置类的 @Bean 方法
7. 注册所有 BeanDefinition 到 BeanFactory
```

#### 步骤 11: finishBeanFactoryInitialization()

```java
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 1. 初始化 ConversionService
    beanFactory.addBeanPostProcessor(new ConversionServiceBeanPostProcessor());
    
    // 2. 初始化 LoadTimeWeaver
    
    // 3. 预先实例化所有单例 Bean（除了工厂 Bean）
    beanFactory.preInstantiateSingletons();
}
```

##### preInstantiateSingletons()

```java
public void preInstantiateSingletons() throws BeansException {
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        
        // 跳过非单例、抽象、非延迟加载的 Bean
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                // 处理工厂 Bean
                FactoryBean<?> factory = getResolvedFactoryBean(beanName);
                Object bean = factory.getObject();
            } else {
                // 获取普通 Bean（触发完整生命周期）
                getBean(beanName);
            }
        }
    }
}
```

#### 步骤 12: finishRefresh()

```java
protected void finishRefresh() {
    // 清除资源缓存
    clearResourceCaches();
    
    // 发布 ContextRefreshedEvent
    publishEvent(new ContextRefreshedEvent(this));
    
    // 注册 LiveBeansView MBean（JMX 支持）
    LiveBeansView.registerApplicationContext(this);
}
```

***

## Bean 生命周期

### 完整生命周期顺序

```
1. 实例化 (Instantiation)
   └─> 调用构造函数或工厂方法

2. 属性填充 (Populate Bean Properties)
   └─> 依赖注入 (@Autowired)

3. BeanNameAware.setBeanName()
   └─> 如果 Bean 实现了 BeanNameAware

4. BeanFactoryAware.setBeanFactory()
   └─> 如果 Bean 实现了 BeanFactoryAware

5. ApplicationContextAware.setApplicationContext()
   └─> 如果 Bean 实现了 ApplicationContextAware

6. BeanPostProcessor.postProcessBeforeInitialization()
   └─> 所有 BPP 的 before 方法

7. InitializingBean.afterPropertiesSet()
   └─> 如果实现了 InitializingBean

8. @PostConstruct 方法
   └─> 如果有标注的方法

9. 自定义 init-method
   └─> 如果在配置中指定

10. BeanPostProcessor.postProcessAfterInitialization()
    └─> 所有 BPP 的 after 方法（AOP 代理在此处创建）

11. Bean 就绪可用

12. （销毁时）@PreDestroy 方法

13. （销毁时）DisposableBean.destroy()

14. （销毁时）自定义 destroy-method
```

### Aware 接口

| 接口 | 回调方法 | 说明 |
|------|----------|------|
| `BeanNameAware` | `setBeanName(String)` | 设置 Bean 的名称 |
| `BeanFactoryAware` | `setBeanFactory(BeanFactory)` | 注入 BeanFactory |
| `ApplicationContextAware` | `setApplicationContext(ApplicationContext)` | 注入 ApplicationContext |
| `ResourceLoaderAware` | `setResourceLoader(ResourceLoader)` | 注入资源加载器 |
| `ApplicationEventPublisherAware` | `setApplicationEventPublisher(...)` | 注入事件发布器 |

***

## Web 容器启动

### ServletWebServerApplicationContext

对于 Web 应用，使用的是特殊的 ApplicationContext：

```java
public class ServletWebServerApplicationContext extends WebApplicationContext {
    
    @Override
    protected void onRefresh() {
        super.onRefresh();
        // 创建和启动嵌入式 Web 服务器
        refreshWebServer();
    }
    
    private void refreshWebServer() {
        if (this.webServer == null) {
            // 创建新的 Web 服务器
            this.webServer = startWebServer();
        }
    }
    
    protected WebServer startWebServer() {
        // 获取 WebServerFactoryBean
        WebServer webServer = this.beanFactory.getBean(WebServer.class);
        return webServer;
    }
}
```

### 嵌入式服务器创建流程

```
1. 根据 classpath 选择服务器类型（Tomcat/Jetty/Undertow）
2. 创建对应的 WebServerFactory
3. 应用 WebServerFactoryCustomizer 进行定制
4. 创建 ServletContext
5. 注册 DispatcherServlet
6. 启动服务器并监听端口
```

### Tomcat 自动配置

```java
@Configuration
@ConditionalOnClass({Servlet.class, Tomcat.class})
@ConditionalOnMissingBean({ServletWebServerFactory.class})
public class TomcatWebServerFactoryAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
        return new TomcatServletWebServerFactory();
    }
    
    @Bean
    @ConditionalOnMissingBean
    public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(
            Environment environment,
            ServerProperties serverProperties,
            TomcatServerProperties tomcatProperties) {
        return new TomcatWebServerFactoryCustomizer(environment, 
                                                   serverProperties, 
                                                   tomcatProperties);
    }
}
```

### WebServerFactoryCustomizer

```java
public class TomcatWebServerFactoryCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
    
    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        // 应用通用服务器属性
        this.serverProperties.apply(factory);
        
        // 应用 Tomcat 特定属性
        this.tomcatProperties.addAdditionalTomcatConnectors(factory);
        
        // 配置连接器
        factory.addConnectorCustomizers(connector -> {
            this.tomcatProperties.configureConnector(connector);
        });
    }
}
```

***

## 启动完成回调

### afterRefresh()

```java
protected void afterRefresh(ConfigurableApplicationContext context, String[] args) {
    // ServletWebServerApplicationContext 在此处启动 Web 服务器
    if (context instanceof WebServerApplicationContext wsc) {
        try {
            WebServer webServer = wsc.getWebServer();
            if (webServer != null) {
                webServer.start();
            }
        }
        catch (Throwable ex) {
            throw new IllegalStateException("Failed to start WebServer", ex);
        }
    }
}
```

### 执行 Runners

```java
private void callRunners(ConfigurableApplicationContext context, String[] args) {
    Collection<? extends CommandLineRunner> commandLineRunners = 
        context.getBeansOfType(CommandLineRunner.class).values();
    Collection<? extends ApplicationRunner> applicationRunners = 
        context.getBeansOfType(ApplicationRunner.class).values();
    
    // 合并并按顺序排序
    List<Runnable> runners = new ArrayList<>();
    runners.addAll(commandLineRunners);
    runners.addAll(applicationRunners);
    sortRunners(runners);
    
    // 执行所有 runners
    for (Runnable runner : runners) {
        try {
            runner.run();
        }
        catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }
}
```

### CommandLineRunner vs ApplicationRunner

```java
// CommandLineRunner - 接收原始命令行参数
public interface CommandLineRunner {
    void run(String... args) throws Exception;
}

// ApplicationRunner - 接收封装后的参数
public interface ApplicationRunner {
    void run(ApplicationArguments args) throws Exception;
}
```

***

## 应用事件生命周期

Spring Boot 定义了完整的应用生命周期事件：

### 事件发生顺序

```
┌─────────────────────────────────────────────────────────────┐
│ 1. ApplicationStartingEvent                                 │
│    └─ 最早发布，此时只有 SpringApplication 可用                 │
├─────────────────────────────────────────────────────────────┤
│ 2. ApplicationEnvironmentPreparedEvent                      │
│    └─ Environment 已准备完成                                  │
├─────────────────────────────────────────────────────────────┤
│ 3. ApplicationContextInitializedEvent                       │
│    └─ ApplicationContext 已创建并初始化                        │
├─────────────────────────────────────────────────────────────┤
│ 4. ApplicationPreparedEvent                                 │
│    └─ 上下文已准备，但未刷新                                   │
├─────────────────────────────────────────────────────────────┤
│ 5. ApplicationStartedEvent                                  │
│    └─ 上下文已刷新，Runner 尚未执行                              │
├─────────────────────────────────────────────────────────────┤
│ 6. AvailabilityChangeEvent (LivenessState.CORRECT)          │
│    └─ 应用存活                                                 │
├─────────────────────────────────────────────────────────────┤
│ 7. ApplicationReadyEvent                                    │
│    └─ Runner 已执行，应用完全就绪                               │
├─────────────────────────────────────────────────────────────┤
│ 8. AvailabilityChangeEvent (ReadinessState.ACCEPTING_TRAFFIC)│
│    └─ 可以接受流量                                             │
└─────────────────────────────────────────────────────────────┘

异常情况：
┌─────────────────────────────────────────────────────────────┐
│ ApplicationFailedEvent                                      │
│    └─ 启动失败时发布                                          │
└─────────────────────────────────────────────────────────────┘
```

### 事件监听示例

```java
@Component
public class StartupEventListener implements ApplicationListener<ApplicationReadyEvent> {
    
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        // 应用完全就绪后的处理逻辑
        ApplicationContext context = event.getApplicationContext();
        Duration timeTaken = event.getTimeTaken();
        // ...
    }
}
```

***

## 优雅关闭 (Graceful Shutdown)

### 关闭钩子注册

```java
public ConfigurableApplicationContext run(String... args) {
    // ...
    
    // 注册 JVM 关闭钩子
    shutdownHooks.addCloseHook(context::close);
    
    // 或者使用传统的 shutdown hook
    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
        try {
            context.close();
        }
        catch (Exception e) {
            // 处理异常
        }
    }));
    
    // ...
}
```

### 上下文关闭流程

```java
public void close() {
    synchronized (this.startupShutdownMonitor) {
        doClose();
    }
}

protected void doClose() {
    if (this.active.compareAndSet(true, false)) {
        // 1. 发布 ContextClosedEvent
        publishEvent(new ContextClosedEvent(this));
        
        // 2. 关闭嵌入式 Web 服务器
        if (this.webServer != null) {
            this.webServer.stop();
        }
        
        // 3. 销毁所有单例 Bean
        destroyBeans();
        
        // 4. 关闭父上下文
        closeParent();
        
        // 5. 发布 ClosedEvent
        publishEvent(new ClosedEvent(this));
    }
}
```

### Bean 销毁回调

```java
// 方式 1: @PreDestroy
@Component
public class MyBean {
    @PreDestroy
    public void cleanup() {
        // 清理资源
    }
}

// 方式 2: DisposableBean
@Component
public class MyBean implements DisposableBean {
    @Override
    public void destroy() throws Exception {
        // 清理资源
    }
}

// 方式 3: Closeable/AutoCloseable
@Component
public class MyBean implements Closeable {
    @Override
    public void close() throws Exception {
        // 清理资源
    }
}

// 方式 4: 自定义 destroy-method
@Bean(destroyMethod = "shutdown")
public MyBean myBean() {
    return new MyBean();
}
```

### 退出码机制

```java
@Component
public class ExitCodeBean implements ExitCodeGenerator {
    
    @Override
    public int getExitCode() {
        // 返回特定的退出码
        return 100;
    }
}

// 在 SpringApplication.exit() 中使用
int exitCode = SpringApplication.exit(context, () -> 100);
System.exit(exitCode);
```

***

## 启动流程图

```
┌──────────────────────────────────────────────────────────────────────────────┐
│                           Spring Boot 启动流程                                │
└──────────────────────────────────────────────────────────────────────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  main() 方法调用               │
                    │  SpringApplication.run()       │
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  1. 创建 SpringApplication      │
                    │     - 推断应用类型              │
                    │     - 设置 ClassLoader         │
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  2. 创建启动监听器              │
                    │     SpringApplicationRunListeners│
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  3. 发布 ApplicationStartingEvent│
                    │     LoggingApplicationListener  │
                    │     初始化日志系统              │
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  4. 准备 Environment           │
                    │     - 创建 StandardEnvironment │
                    │     - 加载 PropertySources     │
                    │     - 执行 EnvironmentPostProcessor│
                    │     - ConfigDataEnvironmentPostProcessor│
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  5. 发布 ApplicationEnvironmentPreparedEvent│
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  6. 打印 Banner                │
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  7. 创建 ApplicationContext    │
                    │     - ServletWebServerApplicationContext│
                    │     - AnnotationConfigApplicationContext│
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  8. 准备 ApplicationContext    │
                    │     - 设置 Environment         │
                    │     - 执行 ApplicationContextInitializer│
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  9. 发布 ApplicationContextInitializedEvent│
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  10. 加载 BeanDefinition       │
                    │      (refresh() 内部)           │
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌─────────────────────────────────────────────────────┐
                    │                   refresh() 详细流程                  │
                    ├─────────────────────────────────────────────────────┤
                    │  10.1 prepareRefresh()                              │
                    │  10.2 obtainFreshBeanFactory()                       │
                    │  10.3 prepareBeanFactory()                           │
                    │  10.4 postProcessBeanFactory()                       │
                    │  10.5 invokeBeanFactoryPostProcessors()              │
                    │         - ConfigurationClassPostProcessor            │
                    │         - 处理 @Configuration                         │
                    │         - 处理 @ComponentScan                         │
                    │         - AutoConfigurationImportSelector             │
                    │         - 加载自动配置类                              │
                    │         - 应用 @Conditional 条件                       │
                    │  10.6 registerBeanPostProcessors()                   │
                    │  10.7 initMessageSource()                            │
                    │  10.8 initApplicationEventMulticaster()              │
                    │  10.9 onRefresh() ← 创建 WebServer                    │
                    │  10.10 registerListeners()                           │
                    │  10.11 finishBeanFactoryInitialization()             │
                    │         - preInstantiateSingletons()                 │
                    │         - Bean 完整生命周期                           │
                    │  10.12 finishRefresh()                               │
                    └─────────────────────────────────────────────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  11. 发布 ApplicationPreparedEvent│
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  12. afterRefresh()            │
                    │      - 启动嵌入式 Web 服务器       │
                    │      - Tomcat/Jetty/Undertow   │
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  13. 发布 ApplicationStartedEvent│
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  14. 执行 ApplicationRunner/    │
                    │      CommandLineRunner         │
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  15. 发布 ApplicationReadyEvent │
                    │      应用完全就绪！              │
                    └────────────────┬───────────────┘
                                     │
                                     ▼
                    ┌────────────────────────────────┐
                    │  16. 注册关闭钩子               │
                    │      - JVM Shutdown Hook      │
                    │      - 优雅关闭支持            │
                    └────────────────────────────────┘
```

***

## 关键配置文件位置

### Spring Boot 3.x 自动配置加载

```
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
```

### Spring Boot 2.x 及更早版本

```
META-INF/spring.factories
```

### 格式示例

```
# Auto Configuration
org.springframework.boot.autoconfigure.AutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
...

# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.env.SpringBootEnvironmentPostProcessor,\
org.springframework.boot.env.SystemEnvironmentPostProcessor,\
org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor,\
...

# Application Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.devtools.restart.RestartApplicationListener,\
org.springframework.boot.logging.LoggingApplicationListener,\
...
```

***

## 性能优化建议

### 1. 减少自动配置类

```properties
# 排除不需要的自动配置
spring.autoconfigure.exclude=\
    org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration
```

### 2. 使用延迟加载

```java
@Configuration
public class LazyConfig {
    
    @Bean
    @Lazy
    public HeavyBean heavyBean() {
        return new HeavyBean();
    }
}
```

### 3. 并行 Bean 初始化（Spring Boot 3.2+）

```properties
# 启用并行 Bean 初始化
spring.main.lazy-initialization=true
```

### 4. 分层启动

```properties
# 仅加载必要的配置层
spring.config.import=optional:configserver:http://config-server:8888
```

***

## 调试技巧

### 1. 查看自动配置报告

```properties
debug=true
```

### 2. 追踪配置加载

```properties
logging.level.org.springframework.boot.context.config=TRACE
```

### 3. 查看 Condition 评估

```properties
logging.level.org.springframework.boot.autoconfigure=DEBUG
```

### 4. 生成条件评估报告

```java
@SpringBootApplication
public class App {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = 
            SpringApplication.run(App.class, args);
        
        // 输出自动配置报告
        AutoConfigurationReport autoConfigurationReport = 
            AutoConfigurationReport.get(context);
        System.out.println(autoConfigurationReport.formattedOutput());
    }
}
```

***

## 一句话总结

**Spring Boot 启动本质上是：创建 SpringApplication → 初始化日志和环境 → 构建 ApplicationContext → 通过 Condition 机制智能加载自动配置 → 刷新上下文触发 Bean 完整生命周期 → 启动 Web 容器 → 执行启动回调 → 应用就绪。**

***

*本文档基于 Spring Boot 4.0 Snapshot 版本编写，适用于 Spring Boot 2.x/3.x/4.x 系列版本的核心启动流程理解。*
