Dubbo源码|二十、Dubbo服务引入——配置检查更新

356 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第24天,点击查看活动详情

开篇

本文介绍Dubbo服务引入部分的源码分析——配置参数检查。

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;
}

初始化

Invoker代理对象就是在init方法中产生的,下面来看下这代代码。

image.png

这段代码主要过程如下:

  1. 判断是否已经实例化了,如果是直接返回。
  2. 判断bootstrap是否初始化,如果没有的话,进行初始化操作。
  3. 检查和更新参数,这个逻辑和服务提供者很相似,就是把ReferenceBean里的属性的值进行更新,按优先级高低进行覆盖,最终更新为优先级最高的参数值。
  4. 初始化map,将消费者运行时信息、监控信息、应用信息、模块信息等放入map中。
  5. 创建代理对象,并缓存。
  6. 判断服务提供者是否可用。
  7. 分发ReferenceConfig实例化完成事件。

检查更新配置

image.png

checkAndUpdateSubConfigs方法主要是检查并更新配置,主要流程如下:

  1. 判断接口名是否为空,为空直接抛出异常,因为找不到对应的服务。
  2. 检查ReferenceConfig的配置,如果ReferenceConfig中的某些属性如果是空的,那么就从AbstractInterfaceConfigModuleConfigApplicationConfig中获取并赋值给ReferenceConfig对象中对应的属性。
  3. 检查ConsumerConfig是否为空,如果为空的话,给他设置默认值。
  4. 通过DubboSPI加载ConfigInitializer接口的实例,对配置做进步一设置,默认为空。
  5. 刷新配置,通过set方法进行赋值。
  6. 判断引用的服务是否为泛化服务。
  7. 初始化引用服务的元数据信息,并进行缓存。
  8. 在系统中拿到dubbo.resolve.file这个文件并进行读取,这个文件是进行配置consumer的接口的,根据接口名获取到URL信息。
  9. 检查ReferenceConfig的各个配置值是否合法,长度、非法字符等。
  10. 通过DubboSPI调用ConfigPostProcessor实现类,进行配置的后置处理。

Refresh刷新

image.png

这里的刷新是指,要获取并确定ReferenceConfig各个属性值的最终值,按优化及顺序进行赋值,优先级高得会覆盖优先级低的配置。优先级顺序高低逻辑代码位于方法getPrefixedConfiguration

配置覆盖的优先级的默认顺序为:系统变量 > 配置中心应用配置 > 配置中心全局配置 > 注解或xml中定义 > dubbo.properties文件。

一个ReferenceConfig对象的属性值,可能在不同的配置里有不同的值,比如timeout属性,可以按照上锁的优先级去寻找具体的值。

image.png

这里的优先级顺序和服务提供者的逻辑是一样的,这里不再进行赘述。

后记

经过参数的检查和更新,拿到最终的map值,就可以根据map里的值来创建代理对象了,下面来看下map里都有什么值,这些值是最简化的配置,也就是直接使用@DubboReference注解没有加任何参数的值。

image.png

下一篇将介绍如果根据map来创建代理对象的。