2-ServiceConfig 服务配置类初始化工作

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

Dubbo3, 源码

在上一章节进行 Demo 演示的时候,要先将 ServiceConfig 实例构造好以后,才能进行服务的启动,接下来先回顾一下相关的代码部分

回顾示例代码

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<DemoServiceImpl> service = new ServiceConfig<>();

服务配置的建模

如下是一张来自于官网的 UML 继承关系图,这里仅仅列出了当前服务提供者的相关服务配置及相关服务配置继承关系,服务提供者、服务消费者共用的父类型使用红色背景来进行标注

1、AbstractConfig

抽象的配置类型,也是最顶层的服务配置类型,封装着解析配置的实用方法和公共方法

比如:服务id的设置、服务标签名字的处理、服务参数的添加、属性的提取等等

2、AbstractMethodConfig

抽象的方法配置,同样这个类型也是见名知意,服务方法的相关配置处理,这个类型主要用于对服务方法的一些配置信息建模

比如:服务方法的调用超时时间、重试次数、最大并发调用数、负载均衡策略、是否异步调用、是否确认异步发送等等配置信息

PropertiesTypeRemark
timeoutIntegerTimeout for remote invocation in milliseconds.
retriesIntegerRetry times for failed invocations.
activesIntegerMaximum concurrent invocations allowed.
loadbalanceStringLoad balancing strategy for service invocation.
asyncBooleanEnable asynchronous invocation.

3、AbstractInterfaceConfig

抽象的接口配置,与前面介绍的方法配置类似,该类型是对服务接口的建模

比如:暴漏服务的接口名字、服务接口的版本号、按远程引用服务分组客户/提供方、服务元数据、服务接口的本地impl类名、服务监控配置

对于生成动态代理的策略,可以选择两种策略:jdk、javassist,容错类型等等配置

PropertiesTypeRemark
interfaceNameStringInterface name of the exported service.
versionStringVersion of the remote service referenced by the consumer/provider.
groupStringGroup of the remote service referenced by the consumer/provider.
serviceMetadataServiceMetadataService metadata configuration.
localStringLocal implementation class name for the service interface.
proxyStringStrategy for generating dynamic agents (options: “jdk” or “javassist”).
monitorMonitorConfigService monitoring configuration.
applicationApplicationConfigApplication configuration for the service.

Dubbo 服务要关注的 ApplicationConfig 应用配置建模

PropertiesTypeRemark
nameStringThe Application name.
versionStringThe application version.
qosEnableBooleanWhether to enable Quality of Service (QoS) or not.
qosCheckBooleanWhether QoS should start successfully or not, will check qosEnable first.
qosHostStringThe QoS host to listen.
qosPortIntegerThe QoS port to listen.

4、ServiceConfigBase

服务的基础配置类,这个类型仍旧是个抽象的类型,提取了一些基础的配置

比如:导出服务的接口类、服务名称、接口实现的引用类型、提供者配置、是否是通用服务 GenericService

PropertiesTypeRemark
interfaceClassThe interface class of the exported service.
refTThe provider configuration for this service.
ProviderProviderConfigThe provider configuration for this service.
genericStringIndicates whether the service is a GenericService.
If set, this means that the service is a generic service that can handle multiple types.

5、ServiceConfig

服务配置实现类,上面的类型都是抽象类型不能作为具体存在的事物,这个类型是我们出现的第一个服务配置实现类型

服务配置实现类已经从父类型中继承了这么多的属性,这里主要为实现服务提供了一些配置如服务的协议配置

比如:服务代理工厂、服务提供者模型、是否导出服务、导出的服务列表、服务监听器等等

服务的代理工厂 JavassistProxyFactory 是将生成导出服务代理的 ProxyFactory 实现,是其默认实现

6、ServiceBean

服务工厂Bean,这个主要是 Spring 模块来简化配置的一个服务工厂 Bean

不仅继承服务配置类所有属性、方法,还针对 Spring 提供的接口作出了对应的扩展实现

比如:InitializingBean#afterPropertiesSet 初始化属性、DisposableBean#destroy Bean 销毁方法、ApplicationContextAware#setApplicationContext 填充应用上下文、BeanNameAware#setBeanName 填充 BeanName、ApplicationEventPublisherAware#setApplicationEventPublisher 填充应用事件发布者

ServiceConfig 构造器初始化

ServiceConfig<DemoServiceImpl> service = new ServiceConfig<>();

根据 JAVA 基础构造器知识,构造器首行都会有个 super 方法来调用父类的构造器

当前这个 super 方法可以不写但是 JAVA 编译器底层会为我们默认加上这么一行 super() 代码来调用父类构造器的

对于上面我提到的这几个构造器根据代码被调用的先后顺序,这里重点说几个重要的,代码执行的先后顺序:AbstractConfig -> AbstractMethodConfig -> AbstractInterfaceConfig -> AbstractServiceConfig -> ServiceConfigBase -> ServiceConfig

AbstractConfig 构造器初始化

public AbstractConfig() {
  // ScopeModel 为空不处理
  this(null);
}

Dubbo 3.3.x 版本不会填充 ScopeModel 进行初始化操作,而在 Dubbo 3.1.0 之前的版本都会初始化一个 ApplicationModel 应用域对象,在这里不详细展开,等后面到执行的地方再具体分析。

image-20250514154031956

AbstractMethodConfig 构造器初始化

public AbstractMethodConfig() {}

Dubbo 3.3.x 版本中是空实现,不会有额外的初始化工作,而在 Dubbo 3.1.0 之前的版本都会初始化调用 ApplicationModel#defaultModel#getDefaultModule 方法获取模块域对象,在这里不详细展开,等后面到执行的地方再具体分析。

image-20250514155115099

AbstractInterfaceConfig 构造器初始化

public AbstractInterfaceConfig() {}

Dubbo 3.3.x 版本中是空实现,不会有额外的初始化工作,而在 Dubbo 3.1.0 之前的版本也不会有相关的操作,后面用到该类的方法会再具体介绍

image-20250514161116691

ServiceConfigBase 构造器初始化

public ServiceConfigBase() {
  // 服务元数据对象创建
  serviceMetadata = new ServiceMetadata();
  // 为服务元数据对象
  serviceMetadata.addAttribute("ORIGIN_CONFIG", this);
}

注意: ServiceMetadata 类目前在 Dubbo 中没有用法

与服务级别相关的数据,例如名称、版本、业务服务的类加载器、安全信息等,还带有用于扩展的 AttributeMap。

服务配置对象的创建过程就这样结束了,当然有一些细节会放到后面来写 上面主要顺序是按照代码执行顺序来写的

下一章节具体来介绍 Framework、Application、Module 域模型的初始化工作

参考文献

https://www.ktyhub.com/zh/chapter_dubbo/2-serviceconfig-config/

vnjohn

作者

vnjohn

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