20. Dubbo服务引入 - 配置检查更新
大约 3 分钟
1. 开篇
本文介绍Dubbo服务引入部分的源码分析——配置参数检查。
从@DubboReference注解解析的文中,我们知道在生成代理对象的地方是调用了ReferenceBean.get()
或者说是ReferenceConfig.get()
方法产生的。
来看一下这个get
方法,先判断是否被销毁,再判断ref
属性是否有值,如果没有的话进行初始化操作,然后再把ref
返回,这个ref
就是我们所说的Invoker
代理对象。
public synchronized T get() {
if (destroyed) {
throw new IllegalStateException("The invoker of ReferenceConfig(" + url + ") has already destroyed!");
}
if (ref == null) {
init();
}
return ref;
}
2. 初始化
Invoker
代理对象就是在init
方法中产生的,下面来看下这代代码。
这段代码主要过程如下:
- 判断是否已经实例化了,如果是直接返回。
- 判断
bootstrap
是否初始化,如果没有的话,进行初始化操作。 - 检查和更新参数,这个逻辑和服务提供者很相似,就是把
ReferenceBean
里的属性的值进行更新,按优先级高低进行覆盖,最终更新为优先级最高的参数值。 - 初始化map,将消费者运行时信息、监控信息、应用信息、模块信息等放入map中。
- 创建代理对象,并缓存。
- 判断服务提供者是否可用。
- 分发
ReferenceConfig
实例化完成事件。
3. 检查更新配置
checkAndUpdateSubConfigs
方法主要是检查并更新配置,主要流程如下:
- 判断接口名是否为空,为空直接抛出异常,因为找不到对应的服务。
- 检查
ReferenceConfig
的配置,如果ReferenceConfig
中的某些属性如果是空的,那么就从AbstractInterfaceConfig
、ModuleConfig
、ApplicationConfig
中获取并赋值给ReferenceConfig
对象中对应的属性。 - 检查
ConsumerConfig
是否为空,如果为空的话,给他设置默认值。 - 通过
DubboSPI
加载ConfigInitializer
接口的实例,对配置做进步一设置,默认为空。 - 刷新配置,通过set方法进行赋值。
- 判断引用的服务是否为泛化服务。
- 初始化引用服务的元数据信息,并进行缓存。
- 在系统中拿到
dubbo.resolve.file
这个文件并进行读取,这个文件是进行配置consumer的接口的,根据接口名获取到URL信息。 - 检查
ReferenceConfig
的各个配置值是否合法,长度、非法字符等。 - 通过
DubboSPI
调用ConfigPostProcessor
实现类,进行配置的后置处理。
4. Refresh刷新
这里的刷新是指,要获取并确定ReferenceConfig
各个属性值的最终值,按优化及顺序进行赋值,优先级高得会覆盖优先级低的配置。优先级顺序高低逻辑代码位于方法getPrefixedConfiguration
。
配置覆盖的优先级的默认顺序为:系统变量 > 配置中心应用配置 > 配置中心全局配置 > 注解或xml中定义 > dubbo.properties文件。
一个ReferenceConfig
对象的属性值,可能在不同的配置里有不同的值,比如timeout
属性,可以按照上锁的优先级去寻找具体的值。
这里的优先级顺序和服务提供者的逻辑是一样的,这里不再进行赘述。
5. 后记
经过参数的检查和更新,拿到最终的map值,就可以根据map里的值来创建代理对象了,下面来看下map里都有什么值,这些值是最简化的配置,也就是直接使用@DubboReference
注解没有加任何参数的值。
下一篇将介绍如果根据map来创建代理对象的。