3-Framework、Application、Module 域模型的初始化工作

作者: vnjohn / 发表于 2025-05-14 / 专栏: Dubbo 3.3

Dubbo3, 源码

在上一章节主要介绍了 ServiceConfig 服务配置类以及父类的初始化工作,所有类的构造函数都是空实现,也就是说只简单创建了一下实例,没有做其他动作。

Dubbo 3.3 与 Dubbo 3.1 之前的版本差异较大,之前的版本会在 AbstractMethodConfig 完成域模型的初始化动作,但到了 Dubbo 3.3 之后,一切的工作交给开发者自定义扩展实现初始化。

查找了相关资料以及源码部分,发现将域模型的初始化工作推迟后,可能是因为以下几个原因:

1、当应用同时管理多个模块时(多租户隔离)依赖的默认模块可能不符合实际的需求,在 Dubbo 3.1 可以让开发者显式指定模块或应用模型,这样就可以明确知道依赖来源

2、Dubbo 3.x 引入分层模型(FrameworkModel > ApplicationModel > ModuleModel)支持更细粒度的资源隔离,3.0.x 版本会在 AbstractMethodConfig 构造中 自动绑定全局默认模块,违背了“模块化隔离”的设计目标;在 Dubbo 3.1 版本中通过显式传递模型(setModuleModel 方法)确保配置与模块生命周期严格绑定

3、若在 AbstractMethodConfig 构造函数中直接调用 getDefaultModule 会 触发模块级别资源的初始化(如配置中心、元数据中心)假设配置类仅被定义但实际未使用,提前初始化会浪费资源;在 Dubbo 3.1 版本按需加载模块资源,延迟到实际服务暴露或消费阶段,减少启动时间和内存占用

回顾示例代码

private static void startWithBootstrap() {
  // 前面的文章都在说明这个服务配置对象的创建
  ServiceConfig<DemoServiceImpl> service = new ServiceConfig<>();
  service.setInterface(DemoService.class);
  service.setRef(new DemoServiceImpl());

  DubboBootstrap bootstrap = DubboBootstrap.getInstance();
  bootstrap
    .application(new ApplicationConfig("dubbo-demo-api-provider"))
    .registry(new RegistryConfig(REGISTRY_URL))
    .protocol(new ProtocolConfig(CommonConstants.DUBBO, -1))
    .service(service)
    .start()
    .await();
}

上面的代码在上个章节说明了 ServiceConfig 初始化过程,随即设置了当前服务提供者对应的接口 Interface 以及实现类 Ref,随即就是 DubboBootstrap 实例构建了,在其内部做了很多工作,其中就包括域模型的创建、配置等,下一小节来具体分析里面是如何进行工作的

DubboBootstrap bootstrap = DubboBootstrap.getInstance();

3.1 DubboBootstrap 实例构建

/**
 * See {@link ApplicationModel} and {@link ExtensionLoader} for why DubboBootstrap is designed to be singleton.
 */
public static DubboBootstrap getInstance() {
  // 双重检查锁第一次判断空
  if (instance == null) {
    // 为空都进行排队等待
    synchronized (DubboBootstrap.class) {
      // 双重检查锁第二次判断空
      if (instance == null) {
        // 调用重载方法获取对象
        instance = DubboBootstrap.getInstance(ApplicationModel.defaultModel());
      }
    }
  }
  return instance;
}

DubboBootstrap 获取对象重载的 getInstance(ApplicationModel applicationModel) 方法

computeIfAbsent 方法对 hashMap 中指定的 key 值进行计算,若该 key > ApplicationModel 不存在,则添加到 HashMap 中

public static DubboBootstrap getInstance(ApplicationModel applicationModel) {
    return ConcurrentHashMapUtils.computeIfAbsent(
          instanceMap, applicationModel, _k -> new DubboBootstrap(applicationModel));
}

instanceMap 设置为 ConcurrentMap<ApplicationModel, DubboBootstrap> 类型,意味着可以为多个应用模型创建不同的启动器,启动多个服务。

在这篇文章主要分析 ApplicationModel.defaultModel(),即域模型 Model 对象的初始化,DubboBootstrap 的具体作用到后面再进行展开

3.2 域模型作用

之前 Dubbo 都是只有一个作用域的,从 Dubbo 3.x 版本开始加入了这个域模型,通过静态类 ApplicationModel 属性共享来增加域模型,主要原因如下:

1、让 Dubbo 支持多应用部署,这块一些大企业有诉求

2、从架构设计上,解决静态属性资源共享、清理问题

3、分层模型将应用的管理、服务的管理分开

过于抽象,Dubbo 3.x 在启动时需要启动配置中心、元数据中心,配置中心、元数据中心可以归 ApplicationModel 应用模型来管理

Dubbo 作为 RPC 框架也同时也需要启动服务和引用服务,服务级别的管理就交给 ModuleModel 模块模型进行管理

分层次的管理方便开发者理解和处理逻辑,父子级别的模型同时也方便了数据传递

3.3 域模型对象的关系

为了不增加复杂性,这里仅仅列出模型对象类型和类型之间的继承关系,如下所示:

模型对象一共有 4 个,公共的属性和操作放在了域模型中,下面来详细说下这几个模型类型作用

1、ExtensionAccessor 接口

方法返回值说明
getExtensionDirectorExtensionDirector获取父类扩展加载管理器对象
getExtensionLoaderExtensionLoader获取扩展对象
getExtension(type, name)<T> T根据扩展名字获取具体扩展对象
getAdaptiveExtension<T> T获取自适应扩展对象
getDefaultExtension<T> T获取默认扩展对象

2、ScopeModel 模型对象的公共抽象父类

属性说明
internalId内部id用于表示模型树的层次结构
modelName公共模型名称,可被用户设置
desc描述信息
classLoaders类加载器管理
parent父域模型管理
scope当前模型的所属域 ExtensionScope
FRAMEWORK(框架)APPLICATION(应用)MODULE(模块)
SELF(自给自足,为每个作用域创建一个实例,用于特殊的 SPI 扩展,如ExtensionInjector)
extensionDirector具体的扩展加载程序管理器对象的管理
beanFactory域 Bean 工厂管理,一个内部共享 Bean 工厂 ScopeBeanFactory

3、FrameworkModel Dubbo 框架模型,可与多个应用程序共享

属性说明
allInstancesFrameworkModel 实例对象集合
applicationModels所有 ApplicationModel 实例对象集合
pubApplicationModels发布的 ApplicationModel 实例对象集合
FrameworkServiceRepository框架的服务存储库类型对象(数据存储在内存中)
internalApplicationModel内部的应用程序模型对象

4、ApplicationModel 表示正在使用 Dubbo 的应用程序,并存储基本元数据信息,以便在 RPC 调用过程中使用。ApplicationModel 包括许多关于发布服务的 ProviderModel 和许多关于订阅服务的 ConsumerModel

属性说明
moduleModels所有 ModuleModel 实例对象集合
pubModuleModels发布的 ModuleModel 实例对象集合
environment环境信息 Environment 实例对象
configManager配置管理 ConfigManager 实例对象
serviceRepository服务存储库 ServiceRepository 实例对象
deployer应用程序部署器 ApplicationDeployer 实例对象
frameworkModel框架 FrameworkModel 实例对象
internalModule内部的模块模型 ModuleModel 实例对象
defaultModule默认的模块模型 ModuleModel 实例对象

5、ModuleModel 服务模块模型

属性说明
applicationModel所属应用程序模型 ApplicationModel 实例对象
moduleEnvironment模块环境信息 ModuleEnvironment 实例对象
serviceRepository模块服务存储库 ModuleServiceRepository 实例对象
moduleConfigManager模块服务配置管理 ModuleConfigManager 实例对象
deployer模块部署器 ModuleDeployer 实例对象,用于导出和引用服务

通过这几个模型对象的关系,可以了解到这几个模型对象的管理层级从框架到应用程序,然后到模块的管理(FrameworkModel -> ApplicationModel -> ModuleModel),主要用来针对框架、应用程序、模块的存储、发布管理、配置管理

3.3.1 ApplicationModel 模型对象

ApplicationModel.defaultModel()

构建 DubboBootstrap 实例时,会先获取 ApplicationModel 默认模型对象

public static ApplicationModel defaultModel() {
  // should get from default FrameworkModel, avoid out of sync
  return FrameworkModel.defaultModel().defaultApplication();
}

获取应用程序模型必须先通过框架领域模型来获取模型对象,再获取应用程序模型

3.3.2 FrameworkModel 模型对象

使用双重检查锁获取框架模型对象,采用 FrameworkModel 默认模型获取方法:defaultModel

/**
 * 在源码的注释上有这么一句话:在销毁默认的 FrameworkModel 时
 * FrameworkModel.defaultModel() 或 ApplicationModel.defaultModel() 将返回一个损坏的模型,可能会导致不可预知的问题
 * 建议:尽量避免使用默认模型
 * @return the global default FrameworkModel
 */
public static FrameworkModel defaultModel() {
  // 双重校验锁的形式创建单例对象
  FrameworkModel instance = defaultInstance;
  if (instance == null) {
    synchronized (globalLock) {
      // 重置默认框架模型
      resetDefaultFrameworkModel();
      if (defaultInstance == null) {
        defaultInstance = new FrameworkModel();
      }
      instance = defaultInstance;
    }
  }
  Assert.notNull(instance, "Default FrameworkModel is null");
  return instance;
}

FrameworkModel 中重置默认框架模型方法:resetDefaultFrameworkModel

private static void resetDefaultFrameworkModel() {
  // 全局悲观锁,同一个时刻只能有一个线程执行重置操作
  synchronized (globalLock) {
    // defaultInstance:当前成员变量 FrameworkModel 类型代表当前默认的 FrameworkModel 类型的实例对象
    if (defaultInstance != null && !defaultInstance.isDestroyed()) {
      return;
    }
    FrameworkModel oldDefaultFrameworkModel = defaultInstance;
    // 存在实例模型列表则直接从内存缓存中查后续不需要创建了
    if (allInstances.size() > 0) {
      // 当前 FrameworkModel 框架实例存在多个,则取第一个作为默认的
      defaultInstance = allInstances.get(0);
    } else {
      defaultInstance = null;
    }
    if (oldDefaultFrameworkModel != defaultInstance) {
      if (LOGGER.isInfoEnabled()) {
        LOGGER.info("Reset global default framework from " + safeGetModelDesc(oldDefaultFrameworkModel)
                    + " to " + safeGetModelDesc(defaultInstance));
      }
    }
  }
}

3.4 创建 FrameworkModel 对象

FrameworkModel 构造器

public FrameworkModel() {
  // 调用父类型 ScopeModel 传递参数
  // 第一个为空代表这是一个顶层的域模型
  // 第二个 FRAMEWORK 表示是框架域 
  // 第三个 false 表示不是内部域
  super(null, ExtensionScope.FRAMEWORK, false);
  synchronized (globalLock) {
    synchronized (instLock) {
      // 内部id用于表示模型树的层次结构,如层次结构:
      // FrameworkModel(索引=1)-> ApplicationModel(索引=2)-> ModuleModel(索引=1,第一个用户模块)
      // 这个 index 变量是 static 类型的为静态全局变量默认值从1开始,如果有多个框架模型对象则 internalId 编号从 1 开始依次递增
      this.setInternalId(String.valueOf(index.getAndIncrement()));
      // register FrameworkModel instance early
      // 将当前新创建的框架实例对象添加到容器中
      allInstances.add(this);
      if (LOGGER.isInfoEnabled()) {
        LOGGER.info(getDesc() + " is created");
      }
      // 初始化框架模型领域对象 -> 调用父类 ScopeModel#initialize 方法
      initialize();
      // 使用 TypeDefinitionBuilder 静态方法 initBuilders 来初始化类型构建器 TypeBuilder 类型集合
      TypeDefinitionBuilder.initBuilders(this);
      // 框架服务存储仓库对象,可以用于快速查询服务提供者信息
      serviceRepository = new FrameworkServiceRepository(this);
      // 获取 ScopeModelInitializer 类型(域模型初始化器)的扩展加载器 ExtensionLoader,每个扩展类型都会创建一个扩展加载器缓存起来
      ExtensionLoader<ScopeModelInitializer> initializerExtensionLoader = this.getExtensionLoader(ScopeModelInitializer.class);
      // 获取 ScopeModelInitializer 类型的支持的扩展集合,当前版本存在 13 个扩展类型实现
      Set<ScopeModelInitializer> initializers = initializerExtensionLoader.getSupportedExtensionInstances();
      // 遍历这些扩展实现调用他们的 initializeFrameworkModel 方法来传递 FrameworkModel 类型对象,细节我们待会再详细说下
      for (ScopeModelInitializer initializer : initializers) {
        initializer.initializeFrameworkModel(this);
      }
      // 创建一个内部的ApplicationModel类型,细节下面说
      internalApplicationModel = new ApplicationModel(this, true);
      // 创建 ApplicationConfig 类型对象同时传递应用程序模型对象internalApplicationModel
      // 获取 ConfigManager 类型对象,然后设置添加当前应用配置对象
      internalApplicationModel
        .getApplicationConfigManager()
        .setApplication(new ApplicationConfig(
          internalApplicationModel, CommonConstants.DUBBO_INTERNAL_APPLICATION));
      // 设置公开的模块名字为常量 DUBBO_INTERNAL_APPLICATION
      internalApplicationModel.setModelName(CommonConstants.DUBBO_INTERNAL_APPLICATION);
    }
  }
}

创建一个 FREMEWORK 框架域模型:ExtensionScope.FRAMEWORK

3.4.1 初始化 ScopeModel

FrameworkModel 框架模型的初始化 initialize 方法,即调用 ScopeModel#initialize 方法

protected void initialize() {
  synchronized (instLock) {
    // 初始化 ExtensionDirector 是一个作用域扩展加载程序管理器
    // ExtensionDirector 支持多个级别,子级可以继承父级的扩展实例
    // 查找和创建扩展实例的方法类似于 Java classloader
    this.extensionDirector = new ExtensionDirector(parent != null ? parent.getExtensionDirector() : null, scope, this);
    // 这个参考了 Spring 生命周期回调思想,添加一个扩展初始化的前后调用的处理器
    // 在扩展初始化之前或之后调用的后处理器,参数类型为 ExtensionPostProcessor
    this.extensionDirector.addExtensionPostProcessor(new ScopeModelAwareExtensionProcessor(this));
    // 创建一个内部共享的域工厂对象,用于注册Bean、创建Bean、获取Bean、初始化Bean等
    this.beanFactory = new ScopeBeanFactory(parent != null ? parent.getBeanFactory() : null, extensionDirector);
    // Add Framework's ClassLoader by default
    // 将当前类的加载器存入加载器集合 classLoaders 中
    ClassLoader dubboClassLoader = ScopeModel.class.getClassLoader();
    if (dubboClassLoader != null) {
      this.addClassLoader(dubboClassLoader);
    }
  }
}

3.4.2 初始化 TypeDefinitionBuilder

初始化类型构造器方法 initBuilders

public static void initBuilders(FrameworkModel model) {
  // 通过域模型 ScopeModel 初始化方法内部创建的 ExtensionDirector,获取所有 TypeBuilder
  Set<TypeBuilder> tbs = model.getExtensionLoader(TypeBuilder.class).getSupportedExtensionInstances();
  BUILDERS = new ArrayList<>(tbs);
}

3.4.3 初始化 FrameworkServiceRepository

框架服务存储仓库对象的初始化,用于快速查询、注册、注销服务提供者信息

public FrameworkServiceRepository(FrameworkModel frameworkModel) {
  this.frameworkModel = frameworkModel;
}

3.4.4 初始化 ScopeModelInitializer

域模型初始化器额获取与初始化(ScopeModelInitializer 类型、initializeFrameworkModel 方法)加载到关于 ScopeModelInitializer 类型的 SPI 扩展实现

// 获取 ScopeModelInitializer 类型(域模型初始化器)的扩展加载器 ExtensionLoader,每个扩展类型都会创建一个扩展加载器缓存起来
ExtensionLoader<ScopeModelInitializer> initializerExtensionLoader = this.getExtensionLoader(ScopeModelInitializer.class);
// 获取 ScopeModelInitializer 类型的支持的扩展集合,这里当前版本存在 13 个扩展类型实现
Set<ScopeModelInitializer> initializers = initializerExtensionLoader.getSupportedExtensionInstances();
// 采用责任链模式调用 initializeFrameworkModel 方法来传递 FrameworkModel 类型对象,细节我们待会再详细说下
for (ScopeModelInitializer initializer : initializers) {
  initializer.initializeFrameworkModel(this);
}

通过 Debug 发现查到域模型初始化器的 SPI 扩展实现有如下 13 种:

image-20250516002135730

AdaptiveScopeModelInitializer
ClusterScopeModelInitializer
MergeableClusterScopeModelInitializer
CommonScopeModelInitializer
ConfigScopeModelInitializer
MetadataScopeModelInitializer
MetricsScopeModelInitializer
RegistryScopeModelInitializer
Fastjson2ScopeModelInitializer
Hessian2ScopeModelInitializer
MeshScopeModelInitializer
RpcScopeModelInitializer
SerializationScopeModelInitializer

3.4.5 ScopeModelInitializer 接口

域模型初始化器接口定义了三个方法,分别是 initializeFrameworkModel、initializeApplicationModel、initializeModuleModel

以 ClusterScopeModelInitializer、CommonScopeModelInitializer、ConfigScopeModelInitializer 域模型初始化器实现的 initializeFrameworkModel 方法举例说明

public class ClusterScopeModelInitializer implements ScopeModelInitializer {
  // 往框架域模型注入 Bean RouterSnapshotSwitcher
  @Override
  public void initializeFrameworkModel(FrameworkModel frameworkModel) {
    ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
    beanFactory.registerBean(RouterSnapshotSwitcher.class);
  }
  // 往应用域模型注入 Bean ClusterUtils
  @Override
  public void initializeApplicationModel(ApplicationModel applicationModel) {
    ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
    beanFactory.registerBean(ClusterUtils.class);
  }
  @Override
  public void initializeModuleModel(ModuleModel moduleModel) {}
}
public class CommonScopeModelInitializer implements ScopeModelInitializer {
  	// 往框架域模型注入 Bean 
  	// FrameworkExecutorRepository、ConverterUtil、SerializeSecurityManager
  	// DefaultSerializeClassChecker、CertManager、ClassHolder
    @Override
    public void initializeFrameworkModel(FrameworkModel frameworkModel) {
        ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
        beanFactory.registerBean(FrameworkExecutorRepository.class);
        beanFactory.registerBean(ConverterUtil.class);
        beanFactory.registerBean(SerializeSecurityManager.class);
        beanFactory.registerBean(DefaultSerializeClassChecker.class);
        beanFactory.registerBean(CertManager.class);
        beanFactory.registerBean(ClassHolder.class);
    }
		// 往应用域模型注入 Bean 
  	// ShutdownHookCallbacks、FrameworkStatusReportService、ConfigurationCache
    @Override
    public void initializeApplicationModel(ApplicationModel applicationModel) {
        ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
        beanFactory.registerBean(ShutdownHookCallbacks.class);
        beanFactory.registerBean(FrameworkStatusReportService.class);
        beanFactory.registerBean(new ConfigurationCache());
    }
  	// 往模块域模型注入 Bean 
  	// ConfigurationCache、SerializeSecurityConfigurator
    @Override
    public void initializeModuleModel(ModuleModel moduleModel) {
        ScopeBeanFactory beanFactory = moduleModel.getBeanFactory();
        beanFactory.registerBean(new ConfigurationCache());
        beanFactory.registerBean(SerializeSecurityConfigurator.class);
    }
}
public class ConfigScopeModelInitializer implements ScopeModelInitializer {
  	// 往框架域添加销毁监听器:FrameworkModelCleaner
    @Override
    public void initializeFrameworkModel(FrameworkModel frameworkModel) {
        frameworkModel.addDestroyListener(new FrameworkModelCleaner());
    }
  	// 往应用域注入 DefaultConfigValidator 校验器
  	// 注入应用发布者并提前设置好应用域模型的 deployer 属性
    @Override
    public void initializeApplicationModel(ApplicationModel applicationModel) {
        ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
        beanFactory.registerBean(DefaultConfigValidator.class);
        // applicationDeployer
        ApplicationDeployer applicationDeployer = beanFactory.registerBean(DefaultApplicationDeployer.class);
        applicationModel.setDeployer(applicationDeployer);
    }
  	// 往模块域模型注入模块发布者并提前设置好模块域模型的 deployer 属性 
    @Override
    public void initializeModuleModel(ModuleModel moduleModel) {
        ScopeBeanFactory beanFactory = moduleModel.getBeanFactory();
        // moduleDeployer
        ModuleDeployer moduleDeployer = beanFactory.registerBean(DefaultModuleDeployer.class);
        moduleModel.setDeployer(moduleDeployer);
    }
}

3.4.6 创建 InternalApplicationModel

创建框架域模型内部的 ApplicationModel 应用域模型对象

// 创建一个内部的 ApplicationModel 类型,细节下面说
internalApplicationModel = new ApplicationModel(this, true);
// 创建 ApplicationConfig 类型对象同时传递应用程序模型对象 internalApplicationModel
// 获取 ConfigManager 类型对象,然后设置添加当前应用配置对象
internalApplicationModel
        .getApplicationConfigManager()
        .setApplication(new ApplicationConfig(
                internalApplicationModel, CommonConstants.DUBBO_INTERNAL_APPLICATION));
// 设置公开的模块名字为常量 DUBBO_INTERNAL_APPLICATION
internalApplicationModel.setModelName(CommonConstants.DUBBO_INTERNAL_APPLICATION);

创建 ApplicationConfig 对象,然后再将其添加至内部应用程序模型中,接着为应用配置管理器设置一个应用配置对象

将这个应用配置的模块名字配置名字设置为 DUBBO_INTERNAL_APPLICATION,应用配置记录着常见的应用配置信息

3.5 创建 ApplicationModel 对象

发现有两处地方会新建 ApplicationModel 对象

1、之前 FrameworkModel 初始化方法内会创建一个内部的 ApplicationModel 类型对象

internalApplicationModel = new ApplicationModel(this, true);
internalApplicationModel
  .getApplicationConfigManager()
  .setApplication(new ApplicationConfig(
    internalApplicationModel, CommonConstants.DUBBO_INTERNAL_APPLICATION));

2、章节 3.3.1 介绍 ApplicationModel 模型对象时,会调用 defaultApplication 方法创建一个外部的 ApplicationModel 类型对象

public ApplicationModel defaultApplication() {
  ApplicationModel appModel = this.defaultAppModel;
  if (appModel == null) {
    // check destroyed before acquire inst lock, avoid blocking during destroying
    checkDestroyed();
    resetDefaultAppModel();
    if ((appModel = this.defaultAppModel) == null) {
      synchronized (instLock) {
        if (this.defaultAppModel == null) {
          this.defaultAppModel = newApplication();
        }
        appModel = this.defaultAppModel;
      }
    }
  }
  Assert.notNull(appModel, "Default ApplicationModel is null");
  return appModel;
}

public ApplicationModel newApplication() {
  synchronized (instLock) {
    return new ApplicationModel(this);
  }
}

protected ApplicationModel(FrameworkModel frameworkModel) {
  this(frameworkModel, false);
}

3.5.1 ApplicationModel 构造器

创建内部、外部的对象都是通过 ApplicationModel(FrameworkModel frameworkModel, boolean isInternal) 构造方法来进行创建,创建的详细看如下代码:

protected ApplicationModel(FrameworkModel frameworkModel, boolean isInternal) {
  // 调用父类型ScopeModel传递参数,这个构造器的传递没与前面看到的FrameworkModel构造器的中的调用参数有些不同
  // 第一个参数我们为frameworkModel代表父域模型,第二个参数标记域为应用程序级别 APPLICATION,第三个参数我们传递的为true代表为内部域
  super(frameworkModel, ExtensionScope.APPLICATION, isInternal);
  synchronized (instLock) {
    Assert.notNull(frameworkModel, "FrameworkModel can not be null");
    // 应用程序域成员变量记录 frameworkModel 对象
    this.frameworkModel = frameworkModel;
    // frameworkModel 对象添加当前应用程序域对象
    frameworkModel.addApplication(this);
    if (LOGGER.isInfoEnabled()) {
      LOGGER.info(getDesc() + " is created");
    }
    // 初始化应用程序
    initialize();
    // 创建一个内部的模块模型对象
    this.internalModule = new ModuleModel(this, true);
    // 创建一个独立服务存储对象
    this.serviceRepository = new ServiceRepository(this);
    // 获取应用程序初始化监听器 ApplicationInitListener 扩展
    ExtensionLoader<ApplicationInitListener> extensionLoader = this.getExtensionLoader(ApplicationInitListener.class);
    // 如果存在应用程序初始化监听器扩展则执行这个初始化方法,在当前的版本还未看到有具体的扩展实现类型
    Set<String> listenerNames = extensionLoader.getSupportedExtensions();
    for (String listenerName : listenerNames) {
      extensionLoader.getExtension(listenerName).init();
    }
    // 初始化扩展(这个是应用程序生命周期的方法调用,这里调用初始化方法
    initApplicationExts();
    // 获取域模型初始化器扩展对象列表,然后执行初始化方法
    ExtensionLoader<ScopeModelInitializer> initializerExtensionLoader = this.getExtensionLoader(ScopeModelInitializer.class);
    Set<ScopeModelInitializer> initializers = initializerExtensionLoader.getSupportedExtensionInstances();
    for (ScopeModelInitializer initializer : initializers) {
      initializer.initializeApplicationModel(this);
    }

    Assert.notNull(getApplicationServiceRepository(), "ApplicationServiceRepository can not be null");
    Assert.notNull(getApplicationConfigManager(), "ApplicationConfigManager can not be null");
    Assert.assertTrue(
      getApplicationConfigManager().isInitialized(), "ApplicationConfigManager can not be initialized");
  }
}

调用 FrameworkModel addApplication 方法将应用程序进行添加

void addApplication(ApplicationModel applicationModel) {
  // 检查 FrameworkModel 对象是否已经被标记为销毁状态,如果已经被销毁了则抛出异常无需执行逻辑
  checkDestroyed();
  synchronized (instLock) {
    // 如果还未添加过当前参数传递应用模型
    if (!this.applicationModels.contains(applicationModel)) {
      // 为当前应用模型生成内部id
      applicationModel.setInternalId(buildInternalId(getInternalId(), appIndex.getAndIncrement()));
      this.applicationModels.add(applicationModel);
      if (!applicationModel.isInternal()) {
        this.pubApplicationModels.add(applicationModel);
      }
    }
  }
}

内部 id 生成算法 buildInternalId 方法代码如下:

protected String buildInternalId(String parentInternalId, long childIndex) {
  // FrameworkModel    1
  // ApplicationModel  1.1
  // ModuleModel       1.1.1
  if (StringUtils.hasText(parentInternalId)) {
    return parentInternalId + "." + childIndex;
  } else {
    return "" + childIndex;
  }
}

3.5.2 初始化 ApplicationModel

ApplicationModel#initialize 方法在 3.4.1 介绍过,其实就是调用 ScopeModel#initialize 初始化方法

// 初始化应用程序
initialize();

3.5.3 初始化内部 ModuleModel

// 创建一个内部的模块模型对象
this.internalModule = new ModuleModel(this, true);

创建 ModuleModel 对象作为内部的模块模型,具体的初始化操作在后面再介绍

3.5.4 初始化 ServiceRepository

应用服务存储仓库对象的创建,通过应用模型的内部模型注册服务、获取所有提供者、所有消费者

// 创建一个独立服务存储对象
this.serviceRepository = new ServiceRepository(this);

3.5.5 初始化 initApplicationExts 应用程序扩展方法

private void initApplicationExts() {
  // 这个扩展实现一共有两个可以看下面那个图扩展类型为 ConfigManager、Environment
  Set<ApplicationExt> exts = this.getExtensionLoader(ApplicationExt.class).getSupportedExtensionInstances();
  for (ApplicationExt ext : exts) {
    ext.initialize();
  }
}

image-20250517220224911

3.5.5.1 ConfigManager 初始化方法

先简单说下 ConfigManager 作用:通过 ConcurrentHashMap 无锁配置管理器,用于快速读取操作。写入操作锁带有配置类型的子配置映射,用于安全检查和添加新配置

ConfigManager 实现类中并没有这个初始化方法 initialize,不过 ConfigManager 的父类型 AbstractConfigManager 中是有 initialize 方法的

AbstractConfigManager 初始化方法 initialize 方法如下:

public void initialize() throws IllegalStateException {
  // 乐观锁判断是否初始化过
  if (!initialized.compareAndSet(false, true)) {
    return;
  }
  // 从模块环境中获取组合配置,目前 Environment 中有 6 种重要的配置,我们后面详细说
  CompositeConfiguration configuration = scopeModel.modelEnvironment().getConfiguration();

  // dubbo.config.mode
  // 获取配置模式,配置模式对应枚举类型 ConfigMode,目前有这么几个 STRICT,OVERRIDE,OVERRIDE_ALL,OVERRIDE_IF_ABSENT,IGNORE,这个配置决定了属性覆盖的顺序
  // 当有同一个配置 key 多次出现时,以最新配置为准,还是以最老的那个配置为准,还是配置重复则抛出异常
  // 默认值为严格模式STRICT重复则抛出异常
  String configModeStr = (String) configuration.getProperty(ConfigKeys.DUBBO_CONFIG_MODE);
  try {
    if (StringUtils.hasText(configModeStr)) {
      this.configMode = ConfigMode.valueOf(configModeStr.toUpperCase());
    }
  } catch (Exception e) {
    String msg = "Illegal '" + ConfigKeys.DUBBO_CONFIG_MODE + "' config value [" + configModeStr
      + "], available values " + Arrays.toString(ConfigMode.values());
    logger.error(COMMON_PROPERTY_TYPE_MISMATCH, "", "", msg, e);
    throw new IllegalArgumentException(msg, e);
  }

  // dubbo.config.ignore-duplicated-interface
  // 忽略重复的接口(服务/引用)配置。默认值为false
  String ignoreDuplicatedInterfaceStr = (String) configuration.getProperty(ConfigKeys.DUBBO_CONFIG_IGNORE_DUPLICATED_INTERFACE);
  if (ignoreDuplicatedInterfaceStr != null) {
    this.ignoreDuplicatedInterface = Boolean.parseBoolean(ignoreDuplicatedInterfaceStr);
  }

  // print 打印配置信息
  Map<String, Object> map = new LinkedHashMap<>();
  map.put(ConfigKeys.DUBBO_CONFIG_MODE, configMode);
  map.put(ConfigKeys.DUBBO_CONFIG_IGNORE_DUPLICATED_INTERFACE, this.ignoreDuplicatedInterface);
  logger.info("Config settings: " + map);
}

3.5.5.2 Environment 初始化方法

Environment 是一个与环境配置有关系的类型,先来介绍它的 initialize 方法

public void initialize() throws IllegalStateException {
  // 乐观锁判断是否进行过初始化
  if (initialized.compareAndSet(false, true)) {
    // PropertiesConfiguration: 从系统属性和 dubbo.properties 中获取配置
    this.propertiesConfiguration = new PropertiesConfiguration(scopeModel);
    // SystemConfiguration: 获取的是 JVM 参数 启动命令中 -D 指定的
    this.systemConfiguration = new SystemConfiguration();
    // EnvironmentConfiguration: 从环境变量中获取的配置
    this.environmentConfiguration = new EnvironmentConfiguration();
    // 外部的 Global 配置 config-center global/default config
    this.externalConfiguration = new InmemoryConfiguration("ExternalConfig");
    // 外部的应用配置如:config-center 中的应用配置
    this.appExternalConfiguration = new InmemoryConfiguration("AppExternalConfig");
    // 本地应用配置,如:Spring Environment/PropertySources/application.properties
    this.appConfiguration = new InmemoryConfiguration("AppConfig");
    // 服务迁移配置加载,dubbo2 升级 dubbo3 的一些配置
    loadMigrationRule();
  }
}

/**
 * 服务迁移配置加载 JVM  > env >  代码路径 dubbo-migration.yaml
 */
@Deprecated
private void loadMigrationRule() {
  if (Boolean.parseBoolean(SystemPropertyConfigUtils.getSystemProperty(
    CommonConstants.DubboProperty.DUBBO_MIGRATION_FILE_ENABLE, "false"))) {
    // JVM 参数中获取文件路径配置的 key dubbo.migration.file
    String path = SystemPropertyConfigUtils.getSystemProperty(CommonConstants.DubboProperty.DUBBO_MIGRATION_KEY);
    if (StringUtils.isEmpty(path)) {
      // env 环境变量中获取
      path = System.getenv(CommonConstants.DubboProperty.DUBBO_MIGRATION_KEY);
      if (StringUtils.isEmpty(path)) {
        // 类路径下获取文件 dubbo-migration.yaml
        path = CommonConstants.DEFAULT_DUBBO_MIGRATION_FILE;
      }
    }
    this.localMigrationRule = ConfigUtils.loadMigrationRule(scopeModel.getClassLoaders(), path);
  } else {
    this.localMigrationRule = null;
  }
}

通过 ConfigUtils 中读取迁移规则配置文件,主要就是将文件读取到内存字符串

3.6 创建 ModuleModel 对象

在初始化 ModuleModel 对象时,同时创建了一个内部的 ModuleModel 对象,代码如下:

this.internalModule = new ModuleModel(this, true);

3.6.1 ModuleModel 构造器

protected ModuleModel(ApplicationModel applicationModel, boolean isInternal) {
  // 调用 ScopeModel 传递 3 个参数父模型,模型域为模块域,是否为内部模型为 true
  super(applicationModel, ExtensionScope.MODULE, isInternal);
  synchronized (instLock) {
    // 初始化成员变量 applicationModel
    Assert.notNull(applicationModel, "ApplicationModel can not be null");
    this.applicationModel = applicationModel;
    // 将模块模型添加至应用模型中
    applicationModel.addModule(this, isInternal);
    if (LOGGER.isInfoEnabled()) {
      LOGGER.info(getDesc() + " is created");
    }
    // 初始化模块模型
    initialize();
    // 创建模块服务存储库对象
    this.serviceRepository = new ModuleServiceRepository(this);
    // 初始化模块配置扩展
    initModuleExt();
    // 初始化域模型扩展
    ExtensionLoader<ScopeModelInitializer> initializerExtensionLoader = this.getExtensionLoader(ScopeModelInitializer.class);
    Set<ScopeModelInitializer> initializers = initializerExtensionLoader.getSupportedExtensionInstances();
    for (ScopeModelInitializer initializer : initializers) {
      initializer.initializeModuleModel(this);
    }
    Assert.notNull(getServiceRepository(), "ModuleServiceRepository can not be null");
    // 创建模块配置管理对象
    Assert.notNull(getConfigManager(), "ModuleConfigManager can not be null");
    Assert.assertTrue(getConfigManager().isInitialized(), "ModuleConfigManager can not be initialized");

    // notify application check state
    // 获取应用程序发布对象,通知检查状态
    ApplicationDeployer applicationDeployer = applicationModel.getDeployer();
    if (applicationDeployer != null) {
      applicationDeployer.notifyModuleChanged(this, DeployState.PENDING);
    }
  }
}

调用 ApplicationModel addModule 方法将模块模型进行添加

void addModule(ModuleModel moduleModel, boolean isInternal) {
  synchronized (instLock) {
    // 不存在则添加
    if (!this.moduleModels.contains(moduleModel)) {
      // 检查应用模型是否已销毁
      checkDestroyed();
      // 添加至模块模型成员变量中
      this.moduleModels.add(moduleModel);
      // 设置模块模型内部id,这个内部id生成过程与上面将应用模型添加到框架模型中的方式是一致的
      // 可以参考 3.5.1 将 ApplicationModel 添加至 FrameworkModel 容器中
      moduleModel.setInternalId(buildInternalId(getInternalId(), moduleIndex.getAndIncrement()));
      // 若不是内部模型则添加到公开模块模型中
      if (!isInternal) {
        pubModuleModels.add(moduleModel);
      }
    }
  }
}

3.6.2 初始化 ModuleModel

ModuleModel#initialize 方法在 3.4.1 介绍过,其实就是调用 ScopeModel#initialize 初始化方法

// 初始化模块模型
initialize();

// 初始化模块配置扩展
initModuleExt();
// 初始化域模型扩展
ExtensionLoader<ScopeModelInitializer> initializerExtensionLoader = this.getExtensionLoader(ScopeModelInitializer.class);
Set<ScopeModelInitializer> initializers = initializerExtensionLoader.getSupportedExtensionInstances();
for (ScopeModelInitializer initializer : initializers) {
  initializer.initializeModuleModel(this);
}
Assert.notNull(getServiceRepository(), "ModuleServiceRepository can not be null");
// 创建模块配置管理对象
Assert.notNull(getConfigManager(), "ModuleConfigManager can not be null");
Assert.assertTrue(getConfigManager().isInitialized(), "ModuleConfigManager can not be initialized");

// notify application check state
// 获取应用程序发布对象,通知检查状态
ApplicationDeployer applicationDeployer = applicationModel.getDeployer();
if (applicationDeployer != null) {
  applicationDeployer.notifyModuleChanged(this, DeployState.PENDING);
}

3.6.3 初始化 ModuleServiceRepository

ModuleServiceRepository 是模块模型中用来存储服务的,如下代码:

// 创建模块服务存储库对象
this.serviceRepository = new ModuleServiceRepository(this);

模块服务存储库的构造器,如下代码:

public ModuleServiceRepository(ModuleModel moduleModel) {
  this.moduleModel = moduleModel;
  frameworkServiceRepository = ScopeModelUtil.getFrameworkModel(moduleModel).getServiceRepository();
}

ModuleServiceRepository 存储库中使用框架存储库 FrameworkServiceRepository 来间接存储,这里具体来看看是如何通过模块模型来获取框架服务存储库的

ScopeModelUtil.getFrameworkModel(moduleModel).getServiceRepository();

ScopeModelUtil 工具类获取 getFrameworkMode 代码如下:

public static FrameworkModel getFrameworkModel(ScopeModel scopeModel) {
  if (scopeModel == null) {
    return FrameworkModel.defaultModel();
  }
  // 通过成员变量获取(构造器初始化时将 FrameworkModel 赋值给了 ApplicationModel 的成员变量)
  if (scopeModel instanceof ApplicationModel) {
    // 直接获取
    return ((ApplicationModel) scopeModel).getFrameworkModel();
  } else if (scopeModel instanceof ModuleModel) {
    ModuleModel moduleModel = (ModuleModel) scopeModel;
    // 间接通过 ApplicationModel 获取,不越级获取
    return moduleModel.getApplicationModel().getFrameworkModel();
  } else if (scopeModel instanceof FrameworkModel) {
    return (FrameworkModel) scopeModel;
  } else {
    throw new IllegalArgumentException("Unable to get FrameworkModel from " + scopeModel);
  }
}

3.6.4 ModuleConfigManager 创建和初始化

// 创建模块配置管理对象
Assert.notNull(getConfigManager(), "ModuleConfigManager can not be null");
Assert.assertTrue(getConfigManager().isInitialized(), "ModuleConfigManager can not be initialized");

ModuleConfigManager 构造器代码如下:

public ModuleConfigManager getConfigManager() {
    if (moduleConfigManager == null) {
        moduleConfigManager = (ModuleConfigManager) this.getExtensionLoader(ModuleExt.class).getExtension(ModuleConfigManager.NAME);
    }
    return moduleConfigManager;
}

其初始化方法其实就是如 3.5.5.1 所介绍的 AbstractConfigManager#initialize 方法

3.6.5 初始化 initModuleExt 模块扩展方法

private void initModuleExt() {
  // 目前扩展支持类型: ModuleEnvironment、ModuleConfigManager
  Set<ModuleExt> exts = this.getExtensionLoader(ModuleExt.class).getSupportedExtensionInstances();
  for (ModuleExt ext : exts) {
    ext.initialize();
  }
}

3.6.5.1 ModuleEnvironment 初始化

public void initialize() throws IllegalStateException {
  if (initialized.compareAndSet(false, true)) {
    this.orderedPropertiesConfiguration = new OrderedPropertiesConfiguration(moduleModel);
  }
}

创建 OrderedPropertiesConfiguration 对象,同时会进行相关配置的初始化

public OrderedPropertiesConfiguration(ModuleModel moduleModel) {
  this.moduleModel = moduleModel;
  refresh();
}

public void refresh() {
  properties = new Properties();
  // 有序的配置提供器扩展获取
  ExtensionLoader<OrderedPropertiesProvider> propertiesProviderExtensionLoader = moduleModel.getExtensionLoader(OrderedPropertiesProvider.class);
  Set<String> propertiesProviderNames = propertiesProviderExtensionLoader.getSupportedExtensions();
  if (CollectionUtils.isEmpty(propertiesProviderNames)) {
    return;
  }
  List<OrderedPropertiesProvider> orderedPropertiesProviders = new ArrayList<>();
  for (String propertiesProviderName : propertiesProviderNames) {
    orderedPropertiesProviders.add(propertiesProviderExtensionLoader.getExtension(propertiesProviderName));
  }

  // order the propertiesProvider according the priority descending
  // 根据优先级进行排序,值越小优先级越高
  orderedPropertiesProviders.sort((a, b) -> b.priority() - a.priority());

  // override the properties.
  // 扩展实现
  for (OrderedPropertiesProvider orderedPropertiesProvider : orderedPropertiesProviders) {
    properties.putAll(orderedPropertiesProvider.initProperties());
  }
}

域模型初始化流程图

DubboBootstrap#getInstance 方法会创建 FrameworkModel 框架模型

框架域持有应用内部域、外部域集合模型的引用,可用于对应用模型进行相关的操作

image-20250518011554291

FrameworkModel 框架模型内部会创建一个内部应用域模型,同时还会在 DubboBootstrap#getInstance 方法内部调用 ApplicationModel#defaultModel 方法创建外部应用域模型

应用域持有框架域模型引用,同时持有模块内部域、外部域集合模型的引用

可委托框架域的扩展加载器进行类的加载,同时可对模块域执行相关的操作

image-20250518011644489

Application 应用模型内部会创建一个内部模块域模型,同时还会在 Dubbostrap#service 方法内部创建一个 ModuleModel 外部模块域模型

模块域持有应用域模型引用,可委托应用域的扩展加载器进行类加载、获取配置

image-20250518032339325

参考文献

https://www.ktyhub.com/zh/chapter_dubbo/3-model-init/

vnjohn

作者

vnjohn

后端研发工程师。喜欢探索新技术,空闲时也折腾 AIGC 等效率工具。 可以在 GitHub 关注我了解更多,也可以加我微信(vnjohn) 与我交流。