在上一章节主要介绍了 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 接口
方法 | 返回值 | 说明 |
---|---|---|
getExtensionDirector | ExtensionDirector | 获取父类扩展加载管理器对象 |
getExtensionLoader | ExtensionLoader | 获取扩展对象 |
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 框架模型,可与多个应用程序共享
属性 | 说明 |
---|---|
allInstances | FrameworkModel 实例对象集合 |
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 种:
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();
}
}
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 框架模型
框架域持有应用内部域、外部域集合模型的引用,可用于对应用模型进行相关的操作
FrameworkModel 框架模型内部会创建一个内部应用域模型,同时还会在 DubboBootstrap#getInstance 方法内部调用 ApplicationModel#defaultModel 方法创建外部应用域模型
应用域持有框架域模型引用,同时持有模块内部域、外部域集合模型的引用
可委托框架域的扩展加载器进行类的加载,同时可对模块域执行相关的操作
Application 应用模型内部会创建一个内部模块域模型,同时还会在 Dubbostrap#service 方法内部创建一个 ModuleModel 外部模块域模型
模块域持有应用域模型引用,可委托应用域的扩展加载器进行类加载、获取配置