dubbo的服务引用

分析完dubbo的服务发布再接着看看服务引用,和服务发布一样的,引用服务也是从配置文件开始:
在这里插入图片描述

一. 配置文件开始

<dubbo:reference id="demoService" interface="org.apache.dubbo.demo.service.DemoService" version="2.0.0"
                     group="default"/>

一般引用服务我们可以在xml中配置这样的代码,然后就能在代码中引用到这个服务接口了
那么实际上他也是从schema解析来的
在这里插入图片描述
在这里插入图片描述
重点就在这个org.apache.dubbo.config.spring.ReferenceBean#getObject方法,这个方法来自org.springframework.beans.factory.FactoryBean#getObject,这里涉及到spring的FactoryBean相关知识,后面有空会写一篇这个然后补到这里,略过对这个方法继续跟进会发现到了org.apache.dubbo.config.ReferenceConfig#init
在这里插入图片描述

二. refer刷新Invoker

在这个非常长的方法中,有一个调用是:ref = createProxy(map);,这里就是创建一个代理org.apache.dubbo.config.ReferenceConfig#createProxy
在这里插入图片描述
createProxy中会调用REF_PROTOCOL.refer(interfaceClass, urls.get(0));,那么这个REF_PROTOCOL自然就是一个动态生成的代理类,之前已经讲过这个Protocol的基本概念,这里就不再说了,不了解的同学可以去看看前面的文章:dubbo的服务发布
在这里插入图片描述
那么这里的这个REF_PROTOCOL实际上是:org.apache.dubbo.registry.integration.RegistryProtocol,但是在进入RegistryProtocol之前,会被AOP的Wrapper代理(比如:org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper#refer)拦截到过一遍,然后才进入org.apache.dubbo.registry.integration.RegistryProtocol#refer
在这里插入图片描述

在这个方法的开始registryFactory.getRegistry(url)这个在看dubbo的服务发布的时候讲过了,其实就是建立zookeeper连接,这里就不再说一遍了,不了解可以去看dubbo的zookeeper连接、创建节点、订阅
这里直接进入:org.apache.dubbo.registry.integration.RegistryProtocol#doRefer
在这里插入图片描述
看到有个方法调用:registry.register(directory.getRegisteredConsumerUrl());这个也是一个熟悉的方法,创建zk节点,也是在看dubbo服务发布的时候说过了,不了解的同学可以去看dubbo的zookeeper连接、创建节点、订阅
这里我们跟进去看看创建的节点信息,流程是:

  1. org.apache.dubbo.registry.support.FailbackRegistry#register
  2. org.apache.dubbo.registry.zookeeper.ZookeeperRegistry#doRegister
  3. org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperClient#create(java.lang.String, boolean)
    在这里插入图片描述
    这里就是创建zk节点的地方,这里实际创建的节点是:
  • /dubbo 持久化节点
  • /dubbo/com.alibaba.dubbo.demo.DemoService 持久化节点
  • /dubbo/com.alibaba.dubbo.demo.DemoService/consumers 持久化节点
  • /dubbo/com.alibaba.dubbo.demo.DemoService/consumers/consumer%.......(省略一长串) 临时节点

接下来回到:org.apache.dubbo.registry.integration.RegistryProtocol#doRefer继续往下,会看到:directory.subscribe(toSubscribeUrl(subscribeUrl));跟进去:
在这里插入图片描述
发现这里其实是对zk的订阅,和之前服务发布之后的类似,这理解快速过一遍,代码跟进:

  1. org.apache.dubbo.registry.integration.RegistryDirectory#subscribe
  2. org.apache.dubbo.registry.support.FailbackRegistry#subscribe
  3. org.apache.dubbo.registry.zookeeper.ZookeeperRegistry#doSubscribe

和之前类似的节点订阅,这里订阅了节点:

  • /dubbo/com.alibaba.dubbo.demo.DemoService/providers
  • /dubbo/com.alibaba.dubbo.demo.DemoService/configurators
  • /dubbo/com.alibaba.dubbo.demo.DemoService/routers

在订阅完节点之后,会有一步:notify(url, listener, urls);
在这里插入图片描述
跟进代码到:
在这里插入图片描述
这里saveProperties(url);和服务发布一样的逻辑,把url保存到文件中,这里不一样的地方在于:listener.notify(categoryList)org.apache.dubbo.registry.integration.RegistryDirectory#notify

在这里插入图片描述
这个org.apache.dubbo.registry.integration.RegistryDirectory#refreshOverrideAndInvoker的作用是:重置明细URL后刷新invoker代理(如果有需要)
在这里插入图片描述

  • overrideDirectoryUrl();的作用是:逐个调用注册中心里面的配置,覆盖原来的url,组成最新的url 放入overrideDirectoryUrl 存储

  • refreshInvoker(urls);的作用是:根据 provider urls,重新刷新Invoker,在org.apache.dubbo.registry.integration.RegistryDirectory#refreshInvoker中,根据invokerURL列表转换为invoker列表。如果url已经被转换为invoker,则不在重新引用,直接从缓存中获取,注意如果url中任何一个参数变更也会重新引用;如果传入的invoker列表不为空,则表示最新的invoker列表;如果传入的invokerUrl列表是空,则表示只是下发的override规则或route规则,需要重新交叉对比,决定是否需要重新引用
    在这里插入图片描述

  • Map<String, Invoker<T>> newUrlInvokerMap = toInvokers(invokerUrls);把invokerUrls转换成newUrlInvokerMap,主要是配置有变动的时候生成新的Invoker

  • this.invokers = multiGroup ? toMergeInvokerList(newInvokers) : newInvokers;这一步的作用是如果服务有分组group,那么把provider包装成StaticDirectory进行分组,方便负载处理

  • this.urlInvokerMap = newUrlInvokerMap;这一步是把新的InvokerMap存储在urlInvokerMap

  • destroyUnusedInvokers(oldUrlInvokerMap, newUrlInvokerMap);这一步是检查旧的url 是否在新map里面存在,不存在,就是销毁url对应的Invoker,比如某个provider下线或者有变更,那么对相应的Invoker做更新处理

关于这个dubbo的Directory刷新可以看后面的这篇文章:dubbo的Directory服务目录

到这里创建节点、订阅、通知就完成了,回到:org.apache.dubbo.registry.integration.RegistryProtocol#doRefer
在这里插入图片描述
继续跟进到:cluster.join(directory)这一步的作用是加入集群路由表,这个调用是:org.apache.dubbo.rpc.cluster.Cluster#join,那么这个依然是SPI的动态代理类,这里接直接说调用链路了:

  • org.apache.dubbo.rpc.cluster.Cluster#join
  • org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper#join AOP拦截到Wrapper
  • org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster#join
  • org.apache.dubbo.rpc.cluster.support.FailoverCluster#doJoin
    在这里插入图片描述

这里涉及到集群模式的路由,可以去看后面的这篇文章dubbo的服务调用-集群容错和路由负载

三. 创建代理类

回到org.apache.dubbo.config.ReferenceConfig#createProxy看这一步创建代理类

return (T) PROXY_FACTORY.getProxy(invoker, ProtocolUtils.isGeneric(generic));

跟进代码,这里也是SPI动态生成的,实际上会走到:org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory#getProxy
但是在进入这里之前,会被Wrapper拦截,流程:

  1. org.apache.dubbo.rpc.proxy.wrapper.StubProxyFactoryWrapper#getProxy(org.apache.dubbo.rpc.Invoker<T>, boolean)
  2. org.apache.dubbo.rpc.proxy.AbstractProxyFactory#getProxy(org.apache.dubbo.rpc.Invoker<T>, boolean)
  3. org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory#getProxy
    在这里插入图片描述
    这里实际上就是利用jdk自带的java.lang.reflect.InvocationHandler生成一个代理类InvokerInvocationHandler
    在这里插入图片描述

拿到这个代理类基本服务引用就完成了

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值