博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dubbo源码学习--服务是如何引用的
阅读量:4546 次
发布时间:2019-06-08

本文共 8318 字,大约阅读时间需要 27 分钟。

相关文章:

ReferenceBean

跟服务引用一样,Dubbo的reference配置会被转成ReferenceBean类,ReferenceBean实现了InitializingBean接口,直接看afterPropertiesSet()也就是spring为Bean提供的初始化方法

方法调用顺序afterPropertiesSet() -> getObject() -> get() -> init() -> createProxy()

1071030-20170113142457431-514268490.jpg

afterPropertiesSet()

afterPropertiesSet()作用为装载应用信息、注册、模块、监控等配置,然后调用getObject()

public void afterPropertiesSet() throws Exception {        //.....        setApplication(applicationConfig);        //.....        setModule(moduleConfig);        //.....        super.setRegistries(registryConfigs);        //.....        Boolean b = isInit();        if (b == null && getConsumer() != null) {            b = getConsumer().isInit();        }        if (b != null && b.booleanValue()) {            getObject();        }    }

getObject()

getObject() 返回 get() 执行结果

public Object getObject() throws Exception {        return get();    }

get()

get() 如果接口代理类(ref) 为空则调用 init() 生成接口代理类

public synchronized T get() {        if (destroyed){            throw new IllegalStateException("Already destroyed!");        }        if (ref == null) {            init();        }        return ref;    }

init()

init() 根据配置生成Map 然后调用 createProxy() 生成代理类

1071030-20170113142508416-1514907300.png

ref = createProxy(map);

createProxy()

具体作用见注释

private T createProxy(Map
map) { //1. 创建临时Url URL tmpUrl = new URL("temp", "localhost", 0, map); final boolean isJvmRefer; // 省略部分代码..... //2.判断是否暴漏本地服务 if (isJvmRefer) { URL url = new URL(Constants.LOCAL_PROTOCOL, NetUtils.LOCALHOST, 0, interfaceClass.getName()).addParameters(map); invoker = refprotocol.refer(interfaceClass, url); // 省略部分代码..... } else { //3.判断用户指定URL,指定的URL可能是对点对直连地址,也可能是注册中心URL if (url != null && url.length() > 0) { String[] us = Constants.SEMICOLON_SPLIT_PATTERN.split(url); if (us != null && us.length > 0) { for (String u : us) { URL url = URL.valueOf(u); if (url.getPath() == null || url.getPath().length() == 0) { url = url.setPath(interfaceName); } if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) { urls.add(url.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map))); } else { urls.add(ClusterUtils.mergeUrl(url, map)); } } } } else { //4. 通过注册中心配置拼装URL List
us = loadRegistries(false); if (us != null && us.size() > 0) { for (URL u : us) { URL monitorUrl = loadMonitor(u); if (monitorUrl != null) { map.put(Constants.MONITOR_KEY, URL.encode(monitorUrl.toFullString())); } urls.add(u.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map))); } } if (urls == null || urls.size() == 0) { throw new IllegalStateException("No such any registry to reference " + interfaceName + " on the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", please config
to your spring config."); } } // 5.调用refprotocol.refer() if (urls.size() == 1) { invoker = refprotocol.refer(interfaceClass, urls.get(0)); } else { List
> invokers = new ArrayList
>(); URL registryURL = null; for (URL url : urls) { invokers.add(refprotocol.refer(interfaceClass, url)); if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) { registryURL = url; // 用了最后一个registry url } } if (registryURL != null) { // 有 注册中心协议的URL // 对有注册中心的Cluster 只用 AvailableCluster URL u = registryURL.addParameter(Constants.CLUSTER_KEY, AvailableCluster.NAME); invoker = cluster.join(new StaticDirectory(u, invokers)); } else { // 不是 注册中心的URL invoker = cluster.join(new StaticDirectory(invokers)); } } } // 省略..... // 6.创建服务代理 return (T) proxyFactory.getProxy(invoker); }

RegistryProtocol

refprotocol.refer()

refprotocol.refer() 先后经过修饰类 ProtocolFilterWrapper、ProtocolListenerWrapper 最后执行RegistryProtocol

ProtocolFilterWrapper -> ProtocolListenerWrapper

//ProtocolFilterWrapper    public 
Invoker
refer(Class
type, URL url) throws RpcException { if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) { return protocol.refer(type, url); } return buildInvokerChain(protocol.refer(type, url), Constants.REFERENCE_FILTER_KEY, Constants.CONSUMER); } //ProtocolListenerWrapper public
Invoker
refer(Class
type, URL url) throws RpcException { if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) { return protocol.refer(type, url); } return new ListenerInvokerWrapper
(protocol.refer(type, url), Collections.unmodifiableList( ExtensionLoader.getExtensionLoader(InvokerListener.class) .getActivateExtension(url, Constants.INVOKER_LISTENER_KEY))); }

RegistryProtocol

@SuppressWarnings("unchecked")    public 
Invoker
refer(Class
type, URL url) throws RpcException { // Constants.REGISTRY_KEY: registry // Constants.DEFAULT_REGISTRY: dubbo url = url.setProtocol(url.getParameter(Constants.REGISTRY_KEY, Constants.DEFAULT_REGISTRY)).removeParameter(Constants.REGISTRY_KEY); Registry registry = registryFactory.getRegistry(url); if (RegistryService.class.equals(type)) { return proxyFactory.getInvoker((T) registry, type, url); } // 配置Group信息 // group="a,b" or group="*" Map
qs = StringUtils.parseQueryString(url.getParameterAndDecoded(Constants.REFER_KEY)); // Constants.REFER_KEY:refer String group = qs.get(Constants.GROUP_KEY); if (group != null && group.length() > 0 ) { if ( ( Constants.COMMA_SPLIT_PATTERN.split( group ) ).length > 1 || "*".equals( group ) ) { return doRefer( getMergeableCluster(), registry, type, url ); } } return doRefer(cluster, registry, type, url); }

doRefer()

  1. 调用FailbackRegistry.register() 在注册中心注册消费者subscribeUrl
  2. 调用FailbackRegistry.subscribe() 订阅注册中心subscribeUrl
private 
Invoker
doRefer(Cluster cluster, Registry registry, Class
type, URL url) { RegistryDirectory
directory = new RegistryDirectory
(type, url); directory.setRegistry(registry); directory.setProtocol(protocol); // Constants.CONSUMER_PROTOCOL: consumer URL subscribeUrl = new URL(Constants.CONSUMER_PROTOCOL, NetUtils.getLocalHost(), 0, type.getName(), directory.getUrl().getParameters()); //consumer://10.9.22.12/com.**.ShopService?application=test&check=false&dubbo=2.8.4 //&interface=com.**.ShopService&methods=getList&pid=6168&retries=1&revision=1.0-SNAPSHOT //&side=consumer&timeout=6000&timestamp=1484275807134&version=1.0 if (! Constants.ANY_VALUE.equals(url.getServiceInterface()) && url.getParameter(Constants.REGISTER_KEY, true)) { registry.register(subscribeUrl.addParameters(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY, Constants.CHECK_KEY, String.valueOf(false))); } directory.subscribe(subscribeUrl.addParameter(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY + "," + Constants.CONFIGURATORS_CATEGORY + "," + Constants.ROUTERS_CATEGORY)); return cluster.join(directory); }

引用服务时序

1071030-20170113142435619-2038560673.jpg

转载于:https://www.cnblogs.com/javanoob/p/dubbo_reference.html

你可能感兴趣的文章
算法稳定性
查看>>
static关键字详解
查看>>
python删除列表中元素的方法
查看>>
进程与线程(2)- python实现多进程
查看>>
MySQL性能优化的最佳20+条经验
查看>>
GUI线程安全详解(二)
查看>>
编写一个Servlet,将表单提交的商品信息输出到页面中
查看>>
使用.NET Core与Google Optimization Tools实现加工车间任务规划
查看>>
成都Uber优步司机奖励政策(3月22日)
查看>>
How to capture video frames from the camera as images using AV Foundation
查看>>
静态变量、实例变量、局部变量与线程安全
查看>>
Oracle 11.2.0.4.0 Dataguard部署和日常维护(6)-Dataguard Snapshot篇
查看>>
python基础语法_9-2函数式编程
查看>>
js实现文字超出部分用省略号代替实例代码
查看>>
SpringCloud学习笔记(3)——Hystrix
查看>>
选择本地文件file
查看>>
B. Light It Up 思维题
查看>>
如何让自己的内心强大起来
查看>>
JUnit介绍(转)
查看>>
个人所得税
查看>>