一、简介
dubbo consumer 如果没有指定protocol参数,默认会将provider注册的protocol provider url都获取并转换为Invoker放到Directory中。如果consumer指定了protocol则会在Directory中选择相应的protocol provider url转换为Invoker放在Directory中。
二、代码分析
逻辑的主要代码下面4处
1、ReferenceConfig.createProxy()
该方法是服务发现的入口方法,该方法的主要逻辑是创建Invoker对象,并生成Proxy对象。其中有调用的parseUrl(Map<String, String>)方法会将referenceParameters放到url中一个名为"refer"的属性中,代码如下:
1、RegistryProtocol.refer()
该方法会将“refer”属性提出来,然后进入doRefer()方法中获取"protocol"参数值,将protocol参数值做为consumerUrl的protocol,同是将referenceParamters做为consumerUrl的参数,consumerUrl的protocol参数会在后面的服务发现中做为一个条件用于筛选相应protocol的provider url。
2、AbsractDirectory构造函数
在AbstractDirectory的构造函数中也有类似的处理,先从url中取出referenceParamters属性,再将其添加到consumerUrl的参数中, 这样protocol参数也就设置到了consumerUrl的参数中了。
3、RegistryDirectory.toInvokers()
该方法就是筛选对应protocol provider url的逻辑之外:
如果provider url的protocol与consumer指定的protocol不一致,则不会被转换为Invoker对象。checkProtocolValid()代码逻辑如下:
- 如果consumer queryProtocols不为空,则判断consumer queryProtocols是否包含providerUrl.protocol
- 如果consumer queryProtocols为空,则判断consumer dubbo是否支持providerUrl.protocol