客户端注册并引用服务源码分析
getObject() 获得服务的代理对象
- 首先或得在配置文件中的配置的参数信息,封装成map,进行创建代理对象
- 在createProxy() 方法中,主要执行以下两步操作
- 进行 Protocol#refer()操作,该方法主要有以下几步
- 进入到RegistryProtocol#refer()方法中,打开一个zookeeper的连接 zookeeperRegistry
- 将consumer 协议注册到zk上,并进行订阅 provide、configurators、routes的变化,这里主要是将服务的列表信息存储到RegistryDirectory,并进行notify()进行及时的获得服务列表的变化以及将服务列表进行持久化到本地地址中。
- 最后根据熔断和降级的策略,一层层的将RegistryDirectory 封装成Invoker :MockClusterInvoker(FailoverClusterInvoker(Directory)))
-
获得代理对象,将上步获得Invoker 进行封装获得代理对象
此时获得一个代理对象,并将上步中的Invoke通过JavassistProxyFactory 再次进行包装,最后的结果是:Proxy0(InvokerInvocationHandler(MockClusterInvoker(FailoverClusterInvoker(Directory)))))
- 进行 Protocol#refer()操作,该方法主要有以下几步
客户端初始化启动过程
ReferenceBean
启动入口
public class ReferenceBean<T> extends ReferenceConfig<T>
implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {
@Override
public Object getObject() throws Exception {
return get();
}
@Override
public Class getObjectType() {return null;}
@Override
public boolean isSingleton() {return false;}
@Override
public void afterPropertiesSet() throws Exception {
//启动入口
getObject();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {}
}
客户端启动主要做了什么?
从
com.alibaba.dubbo.config.ReferenceConfig#createProxy
创建代理对象核心入口开始说起
将
consumer://
协议注册到zk上,并订阅zk其他三个目录的变化,并拿到服务方提供的服务列表,并创建
Proxy0(InvokerInvocationHandler(MockClusterInvoker))
代理对象
@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
private T createProxy(Map<String, String> map) {
// 当只有一个注册中心的时候
if (urls.size() == 1) {
// refprotocol = Protocol$Adaptive ,==>
// ProtocolListenerWrapper(ProtocolFilterWrapper(RegistryProtocol()))
// invoker = MockClusterInvoker
invoker = refprotocol.refer(interfaceClass, urls.get(0));
}
// 创建服务代理
// proxyFactory = ProxyFactory$Adaptive ==>
// StubProxyFactoryWrapper(JavassistProxyFactory())
// todo 代理的是什么?
// 由于Dubbo 支持服务降级和熔断机制,这里是服务的Invoker实例进行一层层的包装
// 根据顺序依次是Proxy0(InvokerInvocationHandler(Invoker()))
// 由于在Protocol.refer()中进行cluster.join()操作,
// cluster.join() 该方法是将服务封装到RegistryDirectory中,并根据服务的降级和熔断一层层的进行封装
// 最后会封装成 MockClusterInvoker(FailoverClusterInvoker(Directory)))
// 最终返回的代理对象就是 Proxy0(InvokerInvocationHandler(MockClusterInvoker(FailoverClusterInvoker(Directory)))))
return (T) proxyFactory.getProxy(invoker);
}