在上一章节进行 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
抽象的方法配置,同样这个类型也是见名知意,服务方法的相关配置处理,这个类型主要用于对服务方法的一些配置信息建模
比如:服务方法的调用超时时间、重试次数、最大并发调用数、负载均衡策略、是否异步调用、是否确认异步发送等等配置信息
Properties | Type | Remark |
---|---|---|
timeout | Integer | Timeout for remote invocation in milliseconds. |
retries | Integer | Retry times for failed invocations. |
actives | Integer | Maximum concurrent invocations allowed. |
loadbalance | String | Load balancing strategy for service invocation. |
async | Boolean | Enable asynchronous invocation. |
3、AbstractInterfaceConfig
抽象的接口配置,与前面介绍的方法配置类似,该类型是对服务接口的建模
比如:暴漏服务的接口名字、服务接口的版本号、按远程引用服务分组客户/提供方、服务元数据、服务接口的本地impl类名、服务监控配置
对于生成动态代理的策略,可以选择两种策略:jdk、javassist,容错类型等等配置
Properties | Type | Remark |
---|---|---|
interfaceName | String | Interface name of the exported service. |
version | String | Version of the remote service referenced by the consumer/provider. |
group | String | Group of the remote service referenced by the consumer/provider. |
serviceMetadata | ServiceMetadata | Service metadata configuration. |
local | String | Local implementation class name for the service interface. |
proxy | String | Strategy for generating dynamic agents (options: “jdk” or “javassist”). |
monitor | MonitorConfig | Service monitoring configuration. |
application | ApplicationConfig | Application configuration for the service. |
Dubbo 服务要关注的 ApplicationConfig 应用配置建模
Properties | Type | Remark |
---|---|---|
name | String | The Application name. |
version | String | The application version. |
qosEnable | Boolean | Whether to enable Quality of Service (QoS) or not. |
qosCheck | Boolean | Whether QoS should start successfully or not, will check qosEnable first. |
qosHost | String | The QoS host to listen. |
qosPort | Integer | The QoS port to listen. |
4、ServiceConfigBase
服务的基础配置类,这个类型仍旧是个抽象的类型,提取了一些基础的配置
比如:导出服务的接口类、服务名称、接口实现的引用类型、提供者配置、是否是通用服务 GenericService
Properties | Type | Remark |
---|---|---|
interface | Class | The interface class of the exported service. |
ref | T | The provider configuration for this service. |
Provider | ProviderConfig | The provider configuration for this service. |
generic | String | Indicates 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 应用域对象,在这里不详细展开,等后面到执行的地方再具体分析。
AbstractMethodConfig 构造器初始化
public AbstractMethodConfig() {}
Dubbo 3.3.x 版本中是空实现,不会有额外的初始化工作,而在 Dubbo 3.1.0 之前的版本都会初始化调用 ApplicationModel#defaultModel#getDefaultModule 方法获取模块域对象,在这里不详细展开,等后面到执行的地方再具体分析。
AbstractInterfaceConfig 构造器初始化
public AbstractInterfaceConfig() {}
Dubbo 3.3.x 版本中是空实现,不会有额外的初始化工作,而在 Dubbo 3.1.0 之前的版本也不会有相关的操作,后面用到该类的方法会再具体介绍
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/