Consumer消费者Demo示例
1 | xml复制代码<?xml version="1.0" encoding="UTF-8"?> |
在之前的章节中已经知道,Dubbo基于Spring自定义标签规范实现了自定义标签,通过自定义标签完成了bean的加载,并且通过实现监听Spring容器刷新完毕事件启动dubbo客户端。启动客户端伴随着服务发布和服务的订阅。
1 | java复制代码public class DubboConsumer { |
dubbo通过`<dubbo:reference`标签引用服务,之后在程序中通过Spring的Context依赖查找(getBean)的方式获取引用的服务的代理实例。`<dubbo:reference`加载的Bean是ReferenceBean,它实现了FactoryBean接口,getBean时会调用ReferenceBean的getObject()方法,这是获取引用的入口。getBean方法会判断Reference对象是否是空的,如果是空的,调用init方法。代码如下:
1 | java复制代码 @Override |
ReferenceConfig#getObject()获取应用Bean
`ReferenceBean`继承了`ReferenceConfig`,当调用ReferenceBean的getObject()方法会调用`ReferenceBean`的get()方法。
1 | java复制代码 public synchronized T get() { |
ReferenceConfig#createProxy()创建服务代理
1 | java复制代码 @SuppressWarnings({"unchecked", "rawtypes", "deprecation"}) |
创建代理服务会创建Invoker,在引用服务过程中,会判断协议是否为injvm,会根据协议做不同的处理,不是injvm协议会根据构造的配置信息(map)生成url并将url协议有zookeeper://改成registry://,然后通过`Protocol`接口`refer`方法引用服务,与发布服务相似,引用服务的过程也会包装方法的调用链,如下:
1 | diff复制代码- ProtocolListenerWrapper |
在refer的过程中会对一个服务端的引用和一个服务多个服务端的服务进行区分处理,对于有多个服务端的服务会进行集群处理(cluster),会讲invoker列表加入到集群中,在调用过程中会根据集群策略来选择不同的策略进行调用,集群策略实现也实现了SPI机制,
RegistryProtocol#refer引用服务
1 | java复制代码 @Override |
RegistryProtocol#doRefer引用服务
1 | java复制代码 private <T> Invoker<T> doRefer(Cluster cluster, Registry registry, Class<T> type, URL url) { |
RegistryDirectory#subscribe订阅服务
`RegistryProtocol#doRefer`方法,directory.subscribe会按照下面的调用链进行处理,最后调用`ZookeeperRegistry#doSubscribe`方法向zk注册数据订阅接口,并设置监听。
1 | diff复制代码- RegistryDirectory |
1 | java复制代码 @Override |
DubboProtocol#protocolBindingRefer创建Invoker
refer服务创建Invoker时会调用该方法,该方法会通过`getClients`创建网络客户端,创建客户端是会判断客户端是否为共享链接,根据`connections`创建客户端`ExchangeClient`,然后通过`initClient`初始化客户端,初始化过程中会判断是否为延迟的客户端`LazyConnectExchangeClient`,不是延迟客户端,就会通过`connect`连接服务提供者,与服务提供者连接,具体建立连接流程不在这里说明,会在网络通信介绍。
1 | java复制代码 @Override |
总结
Dubbo Consumer整个的启动,引用服务的流程大致就看完了,`ReferenceBean`实现了Spring的`FactoryBean`接口,在使用Spring上下文getBean时就会调用到`ReferenceBean`的getObject方法,这时就会通过创建代理(createProxy),然后通过`Protocol`的`refer`方法引用服务;
引用服务的流程大致可以理解为,通过`DubboProtocol`的`refer`方法创建`DubboInvoker`调用`getClients`方法创建`ExchangeClient`,然后通过`initClient`方法初始化网络客户端,初始化客户端过程中会通过`Exchangers`的`connect`与服务提供者建立连接,后续就是网络客户端与服务端建立连接这里会和服务提供者相似,通过`doOpen`初始化网络客户端,然后调用`doConnect`建立连接。
本文转载自: 掘金