请描述 Spring Boot 的启动流程,包括 SpringApplication 的初始化和 run 方法的核心步骤。

Spring Boot 启动流程详解

Spring Boot 是一个用于简化 Spring 应用程序开发的框架,它提供了一种快速的方式来创建独立的、生产级别的 Spring 应用。它的启动流程相对复杂,但可以总结为几个关键步骤。在这篇文章中,我们将深入探讨 Spring Boot 的启动流程,特别是 SpringApplication 的初始化和 run 方法的核心步骤。

一、SpringApplication 类介绍

SpringApplication 是 Spring Boot 应用程序的核心类。它负责引导和启动应用程序,并处理各种配置和设置。我们可以通过 SpringApplication.run() 方法来启动我们的 Spring Boot 应用。

二、启动流程概述
  1. 创建 SpringApplication 实例:

    • 通常在 main 方法中,我们会创建 SpringApplication 的实例并调用 run 方法。
  2. 准备环境:

    • prepareEnvironment 方法用于准备应用环境(ConfigurableEnvironment)。
  3. 创建应用上下文:

    • createApplicationContext 方法用于创建 Spring 应用上下文。
  4. 加载资源:

    • load 方法用于加载应用的配置和资源。
  5. 注册生命周期监听器:

    • registerListeners 方法用于注册监听器。
  6. 进行自动装配:

    • 通过 refreshContext 方法刷新应用上下文,进行自动装配。
  7. 运行 CommandLineRunner 和 ApplicationRunner:

    • 通过 callRunners 方法执行实现了 CommandLineRunnerApplicationRunner 的实例。
三、核心代码示例

接下来,我们通过 Java 代码来演示以上的过程。

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(MyApplication.class);
        application.run(args);
    }
}

main 方法中,我们创建了一个 SpringApplication 实例,并调用 run 方法开始启动应用程序。下面,我们将对 run 方法内部的关键步骤进行深入分析。

java 复制代码
public ConfigurableApplicationContext run(String... args) {
    // Step 1: 准备环境
    ApplicationContextInitializer<?>[] initializers = getInitializers();
    ConfigurableEnvironment environment = prepareEnvironment(initializers);
    
    // Step 2: 创建 ApplicationContext
    ConfigurableApplicationContext context = createApplicationContext();
    context.setEnvironment(environment);
    
    // Step 3: 注册监听器
    registerListeners(context);
    
    // Step 4: 加载应用配置
    prepareContext(context, environment, initializers);
    
    // Step 5: 刷新上下文
    refreshContext(context);
    
    // Step 6: 执行命令行和应用运行器
    callRunners(context, args);
    
    return context;
}

四、详细流程步骤解析

  1. 准备环境 (prepareEnvironment):

    • 该步骤会读取配置文件(如 application.yml, application.properties)并初始化环境。
    java 复制代码
    protected ConfigurableEnvironment prepareEnvironment(ApplicationContextInitializer<?>[] initializers) {
        ConfigurableEnvironment environment = new StandardEnvironment();
        // 额外的环境配置逻辑
        return environment;
    }
  2. 创建应用上下文 (createApplicationContext):

    • 选择合适的上下文类型(如 AnnotationConfigApplicationContextServletWebApplicationContext)并创建它。
    java 复制代码
    protected ConfigurableApplicationContext createApplicationContext() {
        return new AnnotationConfigApplicationContext();
    }
  3. 注册监听器 (registerListeners):

    • 在应用上下文中注册所有的 ApplicationListener
    java 复制代码
    protected void registerListeners(ConfigurableApplicationContext context) {
        // 注册自定义的 ApplicationListener
    }
  4. 加载配置 (prepareContext):

    • 在这一阶段,应用的主要配置文件被加载,bean 的定义被解析并准备到上下文中。
    java 复制代码
    protected void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, ApplicationContextInitializer<?>[] initializers) {
        // 加载 bean 定义等
    }
  5. 刷新上文 (refreshContext):

    • 在应用上下文刷新过程中,Spring 会加载所有的 bean 并执行相应的初始化。
    java 复制代码
    protected void refreshContext(ConfigurableApplicationContext context) {
        context.refresh();
    }
  6. 调用运行器 (callRunners):

    • Spring Boot 会查找实现了 CommandLineRunnerApplicationRunner 的 bean,并调用它们的 run 方法。
    java 复制代码
    protected void callRunners(ConfigurableApplicationContext context, String[] args) {
        for (CommandLineRunner runner : context.getBeansOfType(CommandLineRunner.class).values()) {
            runner.run(args);
        }
    }

五、最后总结下哈

Spring Boot 的启动流程通过 SpringApplication 类极大地简化了 Spring 应用的初始化过程。上述的各个步骤为我们提供了清晰的框架结构,使得开发者能够快速上手并构建出功能强大的应用程序。Spring Boot 封装了许多复杂的逻辑,使得开发者可以更加专注于业务逻辑的开发,而不必过多关注底层的配置细节。理解这些流程有助于我们在遇到问题时能够更有效地调试与排错。

相关推荐
疯狂成瘾者1 小时前
Java 集合 LinkedList 详解:链表结构、常用方法和队列使用
java·开发语言·链表
lanyxp1 小时前
Sentinel 管不到 SQL 这一层——我写了个 MyBatis SQL 熔断器
java
qq_谁赞成_谁反对1 小时前
甲方IT的成长之路--nginx实战--2604
服务器·数据库·nginx
云水一下2 小时前
从零开始学 PHP 系列(六):MySQL 数据库与 PHP 交互——让数据真正“住”进服务器
数据库·mysql·php
fofantasy2 小时前
NSK LH25FL 升级至 NH25EM 技术规格指南
服务器·网络·数据库·经验分享·规格说明书
炘爚2 小时前
Linux——Redis
数据库·redis·缓存
慧一居士2 小时前
SpringCloud 微服务Feigin 用的完整调用端和被调用的示例
java·spring cloud
CodeStats2 小时前
【虚拟机】 从 CPU 指令到虚拟机隔离:虚拟机就是一个“模拟了完整硬件的普通进程”
java·docker