SpringBoot 启动分析

一、序言

本文简单分析一下 SpringBoot 的启动流程。

二、SpringBoot 启动源码分析

java 复制代码
public ConfigurableApplicationContext run(String... args) {
    // 记录当前时间的纳秒数,用于计算应用程序启动所花费的时间
    long startTime = System.nanoTime();
    // 创建一个默认的引导上下文对象
    DefaultBootstrapContext bootstrapContext = createBootstrapContext();
    // 声明一个可配置的应用程序上下文对象,并初始化为 null
    ConfigurableApplicationContext context = null;
    // 配置 Headless 模式的属性
    configureHeadlessProperty();
    // 获取应用程序运行监听器
    SpringApplicationRunListeners listeners = getRunListeners(args);
    // 通知监听器应用程序即将启动
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    
    try {
        // 创建应用程序参数对象
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        // 准备环境,包括配置文件加载、属性设置等
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        // 配置环境,忽略 Bean 信息
        configureIgnoreBeanInfo(environment);
        // 打印启动横幅
        Banner printedBanner = printBanner(environment);
        // 创建应用程序上下文对象
        context = createApplicationContext();
        // 设置应用程序启动对象
        context.setApplicationStartup(this.applicationStartup);
        // 准备上下文,包括设置环境、监听器、应用程序参数等
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
        
        // 刷新应用程序上下文
        refreshContext(context);
        // 刷新后的操作,如注册关闭钩子等
        afterRefresh(context, applicationArguments);
        
        // 计算应用程序启动所花费的时间
        Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
        // 如果需要记录启动信息,则记录应用程序启动完成的日志
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
        }
        // 通知监听器应用程序已经启动
        listeners.started(context, timeTakenToStartup);
        // 执行应用程序中的所有 ApplicationRunner 和 CommandLineRunner 实例
        callRunners(context, applicationArguments);
    }
    catch (Throwable ex) {
        handleRunFailure(context, ex, listeners);
        throw new IllegalStateException(ex);
    }
    
    try {
        // 计算应用程序准备就绪所花费的时间
        Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
        // 通知监听器应用程序已经准备就绪
        listeners.ready(context, timeTakenToReady);
    }
    catch (Throwable ex) {
        handleRunFailure(context, ex, null);
        throw new IllegalStateException(ex);
    }
    
    // 返回应用程序上下文对象
    return context;
}

三、SpringBoot 启动流程分析

我们可以将 SpringBoot 启动流程归纳为上面的几个大阶段:

  1. 初始化和准备阶段:这个阶段包括记录启动时间、创建引导上下文、配置 Headless 属性、获取运行监听器、环境准备以及打印 Banner 等步骤。这个阶段的主要目标是为接下来的步骤做好准备。
  2. 创建应用程序上下文阶段:这个阶段主要是创建 ApplicationContext 实例,并加载 Bean 定义。这个阶段的主要目标是创建并初始化 Spring 的 IoC 容器。
  3. 刷新应用程序上下文阶段:这个阶段主要是完成 Bean 的初始化,包括调用初始化方法、完成 Bean 的依赖注入等,以及调用所有的 ApplicationRunner 和 CommandLineRunner 的 run 方法。这个阶段的主要目标是完成应用程序的启动。
  4. 就绪阶段:这个阶段的主要目标是确保应用程序已经准备就绪,可以开始接受和处理请求了。
相关推荐
你的人类朋友9 小时前
说说签名与验签
后端
databook9 小时前
Manim实现脉冲闪烁特效
后端·python·动效
RainbowSea10 小时前
12. LangChain4j + 向量数据库操作详细说明
java·langchain·ai编程
RainbowSea10 小时前
11. LangChain4j + Tools(Function Calling)的使用详细说明
java·langchain·ai编程
canonical_entropy13 小时前
AI时代,我们还需要低代码吗?—— 一场关于模型、演化与软件未来的深度问答
后端·低代码·aigc
颜如玉14 小时前
HikariCP:Dead code elimination优化
后端·性能优化·源码
考虑考虑14 小时前
Jpa使用union all
java·spring boot·后端
用户37215742613514 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
bobz96515 小时前
virtio vs vfio
后端
浮游本尊15 小时前
Java学习第22天 - 云原生与容器化
java