本篇是基于Dubbo的2.7.3-release版本.
下图是来自Dubbo官方的的消费者调用时序图
从上一篇 消费者启动过程分析 中,通过JDK的动态代理对象,传入的InnvokeHandler是ReferenceBeanInvocationHandler,这里通过调用注入的@Reference的代理会触发invoke方法的调用,这里的bean对象是触发真实代理对象的分调用. 通过ReferenceBean中get方法中获取通过init方法初始化生成代理对象. ReferenceBeanInvocationHandler中bean就是通过init方法中的createProxy方法中生成代理代理对象. ReferenceBean中Protocol是Protocol@Adaptive(SPI对象生成适配类),调用调用refer方法得到Invoker对象,这里使用到Dubbo的SPI机制特性,如果有注册中心这Protocol加载的扩展协议是RegsitryProtocol,由于Protocol注册有ProtocolFilterWrapper和ProtocolListenerWrapper包装类,所有执行顺序是ProtocolListenerWrapper.refer()--->ProtocolFilterWrapper.refer()--->RegistryProtocol.refer()这种执行顺序执行. 首先会调用ProtocolListenerWrapper的refer方法,这里判断URL的Protocol中的协议是否是Registry的协议,则调用protoco(这里注入的protocol是ProtocolFilterWrapper)的refer方法 然后调用ProtocolFilterWrapper中refer方法,这里判断URL的Protocol中的协议是否是Registry的协议,由于我们配置了zookeeper的注册中心,这里第一个if判断是true,并且这里注入的对象是RegistryProtocol中,并执行RegistryProtocol.refer方法返回Invoker对象. RegistryProtocol的refer方法,这里首先会删除了URL参数中registry的key,并设置协议为Dubbo,接着判断是否注册的信息是否是RegistryService类型的bean,如果是通过ProxyFactoy包装成Invoker返回,然后判断@Reference是否配置group.然后调用doRefer进行服务引用. 创建的RegistryDirectory去注册服务消费者,并且对服务的路由、配置、提供者信息变更的更新.最后通过注入的Cluster(集群的特性后面会详细讲)这个扩展点,调用join方法对多个服务的合并转换成Invoker,并将其注册到ProviderConsumerRegTable这个对象中. AbstractProtocol中refer方法中protocolBindingRefer方法是抽象方法,是具体协议对象,默认DubboProtocol去实现了protocolBindingRefer方法.如果是是否group,最后调用doRefer方法 这里doRefer方法是通过RegistryDirectory向注册中心注册元数据信息,并且订阅注册中心提供者信息,然后通过Cluster.join合并成一个Invoker,默认集群策略是FailOver的,所以这里返回的Invoker对象是FailoverClusterInvoker 服务订阅时,会通过获取注册中心的提供者的URL,并默认使用DubboPrtocol的refer方法重新引用一次 Dubbo中的protocolBindingRefer方法,构建一个DubboInvoker对象,其中第三个参数是获取ExchangeClient[]数组,消费端的远程调用通信就是它完成的(默认是Netty), 这里就是ProxyFactory调用getProxy方法获取的代理对象,这里ProxyFactory注入是实例对象是ProxyFactroy$Adaptive对象,默认是使用JavassistProxyFactory生成Invoker. JavassistProxyFactory的getProxy主要是将通过Protocol转换成的Invoker.通过Dubbo自己实现的Proxy生成代理类.注入到Spring容器中Bean标注@Reference中属性和方法中. 通过调用@Reference的bean方法调用,最终会调用InvokerInvocationHandler的invoke方法,该方法里面是调用Invoker的invoke方法,通过传入RpcInvocation对象,传入method和参数等,通过ExchangeClient调用远程的方法并返回总结:
今天主要是分析Reference执行启动的流程,以及调用的过程,