小工具知识网

当前位置: 首页 > 行业知识 > 【Spring Boot 源码学习】深入 BootstrapContext 及其默认实现

行业知识

【Spring Boot 源码学习】深入 BootstrapContext 及其默认实现

2026-10-20 18:15:52 来源:互联网转载

《Spring Boot ���码学习系列》

深入 BootstrapContext 及其默认实现

  • 一、引言
  • 二、往期内容
  • 三、主要内容
    • 3.1 BootstrapContext
      • 3.1.1 源码初识
      • 3.1.2 get 方法
      • 3.1.3 getOrElse 方法
      • 3.1.4 getOrElseSupply 方法
      • 3.1.5 getOrElseThrow 方法
      • 3.1.6 isRegistered 方法
      • 3.2 ConfigurableBootstrapContext
      • 3.3 DefaultBootstrapContext
        • 3.3.1 源码初识
        • 3.3.2 实现 BootstrapRegistry 接口中的方法
        • 3.3.3 实现 BootstrapContext 接口中的方法
        • 3.3.4 close 方法
        • 四、总结

          一、引言

          书接前文《BootstrapRegistry 详解》,在介绍 BootstrapRegistry 的内部类 InstanceSupplier 的 get 方法时,看到了它的唯一参数 BootstrapContext 接口【即引导上下文】。而这个接口及其默认实现就是本篇要重点介绍的对象,且听我娓娓道来。

          二、往期内容

          在开始本篇的内容介绍之前,我们先来看看往期的系列文章【有需要的朋友,欢迎关注系列专栏】:

          Spring Boot 源码学习
          Spring Boot 项目介绍
          Spring Boot 核心运行原理介绍
          【Spring Boot 源码学习】@EnableAutoConfiguration 注解
          【Spring Boot 源码学习】@SpringBootApplication 注解
          【Spring Boot 源码学习】走近 AutoConfigurationImportSelector
          【Spring Boot 源码学习】自动装配流程源码解析(上)
          【Spring Boot 源码学习】自动装配流程源码解析(下)
          【Spring Boot 源码学习】深入 FilteringSpringBootCondition
          【Spring Boot 源码学习】OnClassCondition 详解
          【Spring Boot 源码学习】OnBeanCondition 详解
          【Spring Boot 源码学习】OnWebApplicationCondition 详解
          【Spring Boot 源码学习】@Conditional 条件注解
          【Spring Boot 源码学习】HttpEncodingAutoConfiguration 详解
          【Spring Boot 源码学习】RedisAutoConfiguration 详解
          【Spring Boot 源码学习】JedisConnectionConfiguration 详解
          【Spring Boot 源码学习】初识 SpringApplication
          【Spring Boot 源码学习】Banner 信息打印流程
          【Spring Boot 源码学习】自定义 Banner 信息打印
          【Spring Boot 源码学习】BootstrapRegistryInitializer 详解
          【Spring Boot 源码学习】ApplicationContextInitializer 详解
          【Spring Boot 源码学习】ApplicationListener 详解
          【Spring Boot 源码学习】SpringApplication 的定制化介绍
          【Spring Boot 源码学习】BootstrapRegistry 详解

          三、主要内容

          注意: 以下涉及 Spring Boot 源码 均来自版本 2.7.9,其他版本有所出入,可自行查看源码。

          3.1 BootstrapContext

          3.1.1 源码初识

          public interface BootstrapContext { T get(Class type) throws IllegalStateException; T getOrElse(Class type, T other); T getOrElseSupply(Class type, Supplier other); T getOrElseThrow(Class type, Supplier instanceSupplier) {// 省略 。。。}

          从 3.1 小节,我们了解了 BootstrapContext 的 4 个获取方法。通过查看上述的源码,我们看到这里只需要分析 getOrElseSupply 和 getOrElseThrow 的实现即可。

          同样在 getOrElseSupply 和 getOrElseThrow 方法中,我们看到了 synchronized (this.instanceSuppliers),这里同 3.3.2 中讲解的一样,都是为了防止多个线程同时修改 instanceSuppliers 对象,导致数据不一致的问题。

          getOrElseSupply 方法的实现也比较简单。如果指定类型的供应者存在,则通过 getInstance 方法从这个供应者中获取对应类型的实例对象;否则,直接从提供者 other 参数中获取。

          getOrElseThrow 方法的实现也好理解。如果指定类型的供应者不存在,则直接从异常供应者中获取一个异常类,并将该异常抛出去即可;否则,通过 getInstance 方法从这个供应者中获取对应类型的实例对象。

          很显然,上述方法最终都需要使用 getInstance 方法,从供应者中获取对应类型的实例对象。我们来看看相关的源码:

          T instance = (T) this.instances.get(type);if (instance == null) {instance = (T) instanceSupplier.get(this);if (instanceSupplier.getScope() == Scope.SINGLETON) {this.instances.put(type, instance);}}return instance;

          简单总结如下:

          • 首先,从 instances 中获取指定类型的实例对象 instance 。
          • 接着,如果 instance 不存在,则继续。
            • 从实例供应者 instanceSupplier 中获取一个实例对象,并赋值给 instance;
            • 如果实例供应者 instanceSupplier 指定的作用域是单例,则将获取的实例对象添加到 instances 中,方便后续直接获取。
            • 最后,直接返回指定类型的实例对象 instance。

              3.3.4 close 方法

              当 BootstrapContext 被关闭且 ApplicationContext 已准备好时,该方法将被调用【后续笔者讲解 Spring Boot 的启动引导过程会涉及到】。

              通过阅读源码,我们可以看到这里触发了一个名为 BootstrapContextClosedEvent 的事件,该事件会多播给所有注册了该事件的监听器,而这些监听器就是通过 3.3.2 小节中提到的 addCloseListener 方法添加的【后续 Huazie 会带大家实操一下】。

              四、总结

              本篇 Huazie 带大家深入了解了 BootstrapContext 及其默认实现,这些内容对我们理解 Spring Boot 的启动引导过程至关重要。下篇 Huazie 将通过自定义 BootstrapRegistry 初始化器实现,来看看引导上下文在 Spring Boot 的启动引导过程中的作用。

上一篇:揭秘Win10企业版激活全攻略,一步步轻松搞定!

下一篇:服务器配置如何提升cpu?