相关博客:
如果不使用注册中心,服务怎么发布?
在之前的博客(https://blog.csdn.net/Dongguabai/article/details/83754289)中介绍过了,如果发布 Dubbo 服务不使用注册中心的话,可以这么配置:
<!--注册中心-Dongguabai,N/A表示不需要依赖注册中心-->
<dubbo:registry address="N/A"/>
在上一篇博客中介绍了在 com.alibaba.dubbo.config.ServiceConfig#doExportUrlsFor1Protocol 方法中,有这样一段代码:
......
......
//如果配置了注册中心
if (registryURLs != null && registryURLs.size() > 0
&& url.getParameter("register", true)) {
for (URL registryURL : registryURLs) {
url = url.addParameterIfAbsent("dynamic", registryURL.getParameter("dynamic"));
URL monitorUrl = loadMonitor(registryURL);
if (monitorUrl != null) {
url = url.addParameterAndEncoded(Constants.MONITOR_KEY, monitorUrl.toFullString());
}
if (logger.isInfoEnabled()) {
logger.info("Register dubbo service " + interfaceClass.getName() + " url " + url + " to registry " + registryURL);
}
Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
Exporter<?> exporter = protocol.export(invoker);
exporters.add(exporter);
}
} else { //如果没有配置注册中心
Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);
Exporter<?> exporter = protocol.export(invoker);
exporters.add(exporter);
}
......
......
上面代码中的 protocol 就是来自:
private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
即就是 Protocol$Adaptive。执行了 Protocol$Adaptive 的 export() 方法:
......
......
public com.alibaba.dubbo.rpc.Exporter export(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.Invoker {
if (arg0 == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");
if (arg0.getUrl() == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");
com.alibaba.dubbo.common.URL url = arg0.getUrl();
String extName = (url.getProtocol() == null ? "dubbo": url.getProtocol());
if (extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
return extension.export(arg0);
}
......
......
又是获取的一个 extension,这个 extension 到底是什么取决于 extName,即来自 url.getProtocol。其实可以猜测这里的 extName 是跟协议有关协议,因为不需要注册中心了,后面直接 exporters.add() 即可。也可以 debug 调试一下,先将注册中心改为 “N/A”:
<!--注册中心-Dongguabai,N/A表示不需要依赖注册中心,集群使用逗号分隔-->
<!--注意要声明id-->
<dubbo:registry id="zk1" address="N/A"/>
<dubbo:registry id="zk2" address="N/A"/>
<!--
<dubbo:registry id="zk1" address="zookeeper://192.168.220.137:2181"/>
<dubbo:registry id="zk2" address="zookeeper://192.168.220.136:2181"/>
-->
发布服务:
我这里是 dubbo 协议,所以这里是 dubbo:
既然这里是 dubbo 了,结合对应关系,这里就是 DubboProtocol:
看看 DubboProtocol 的 export() 方法:
最终还是到了这个方法:com.alibaba.dubbo.common.extension.ExtensionLoader#createExtension
最终还是有个调用链的关系在里面,这就跟上一篇的博客中的一样了,具体可参看 Dubbo 之服务发布和注册(一)。