Dubbo 服务消费 源码
@Refer 注解解析

@Refer注解解析 .png
流程概括
DubboComponentScan注解中使用Import注解注册DubboComponentScanRegistrar,DubboComponentScanRegistrar注册RefereceAnnotationBeanPostProcessor
- 入口为spring的属性填充,
InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法,从中拿到pvs
- 调用
RefereceAnnotationBeanPostProcessor.postProcessPropertyValues
- 从Bean中拿到所有带有注解的方法和属性元数据,构造
AnnotatedInjectionMetadata
- 依次在元数据中找Refrence注解,如果有,依据Refence生成包装类RefrenceName
- 依据RefrenceName在缓存中找实例,没有则创建并缓存
- 查看BeanFactory中是否有该Bean,如果本地有DubboService Bean 添加别名,没有则注册为单例Bean
- 缓存RefrenceBean
- 在RenfenceBean内部创建代理类,返回代理类,返回步骤3,填充到pvs中
服务消费
服务消费.png

流程概括
- 入口为
ReferenceBean的get方法
- 属性填充,将版本、接口名、本机ip等信息填充到map中
- 构建URL
1.)本地消费,从injvm协议对象中拿到invoker实例即可
2.)预设了url,直连服务消费,用户指定的URL,可以是点对点地址或注册中心地址。
用分号分割,如果协议为Registry则注册中心地址后添加refer存储服务消费元数据信息构建URL
其他协议没有添加refer和注册中心协议,默认是Dubbo会直接触发DubboProtocol进行远程消费,不会经过RegistryProtocol去做服务发现
3.)没配置则从本地拿到注册中心URL列表
- 遍历URL列表,为每个URL创建代理Invoker,建立invokerlist
1.)从URL中拿到注册中心名称,从缓存中获取注册中心实例
2.)如果指定单一分组,依据URL参数创建Cluster
指定多个分组或通配符,创建MergeableCluster
3.)创建包装容器类RegistryDirectory用于存储registry、protocol、invoker等,填充registry、protocol等。
4.)注册消费者到注册中心
5.)订阅服务,第一次订阅会进行一次数据拉取,同时触发RegistryDirectory#notify方法,这里的通知数据是某一个类别的全量数据,比如Providers和routers类别数据。当notity providers数据时,在RegistryDirectory#toInvokers方法内完成url到Invoker转换,动态代理
6.)将RegistryDirectory填入ClusterInvoker子类中,返回ClusterInvoker子类
- 如果invokerlist长度大于1,合并为StaticDirectroty,再次包装为ClucterInvoker子类,返回