8 - Dubbo本地服务暴露

腾一部分笔记到csdn

 

1. 本地暴露概述

 
 

2. 源码分析

    在 3* - API 配置(二)之服务提供者 一文中,我们看到 ServiceConfig#export() 方法中,会在配置初始化完成后,调用顺序图的起点 #doExportUrls() 方法,循环registerURLs调用doExportUrlsFor1Protocol开始暴露服务。代码如下:
2.1 doExportUrlsFor1Protocol
#doExportUrlsFor1Protocol(protocolConfig, registryURLs) 方法,基于单个协议,暴露服务。简化代码如下:
1 /**
2:  * 基于单个协议,暴露服务
3:  *
4:  *  @param  protocolConfig 协议配置对象
5:  *  @param  registryURLs 注册中心链接对象数组
6:  */
7 private  void  doExportUrlsFor1Protocol (ProtocolConfig protocolConfig, List<URL> registryURLs)  {
8 :      // ... 【省略】 创建服务 URL 对象
10 :     String scope = url.getParameter(Constants.SCOPE_KEY);
12 :      if  (!Constants.SCOPE_NONE.toString().equalsIgnoreCase(scope)) {
15 :          if  (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {
16 :             exportLocal(url);
17 :         }
19 :          if  (!Constants.SCOPE_LOCAL.toString().equalsIgnoreCase(scope)) {
20 :              // ... 【省略】远程暴露 
21 :         }
22 :     }
23 :      this .urls.add(url);
24 : }
 
ServiceConfig.java
-> 如果协议不等于Injvm,进行本地暴露。因为Injvm的情况下,在InjvmProtocol远程暴露时会暴露本地
-> URL local = URL.valueOf(url.toFullString()).setProtocol(Constants.LOCAL_PROTOCOL).setHost(LOCALHOST).setPort(0); //创建一个本地暴露的URL
-> ServiceClassHolder.getInstance().pushServiceClass(getServiceClass(ref)); 添加服务的真实类名,例如 DemoServiceImpl ,仅用于 RestProtocol 中。
 
-> Exporter<?> exporter = protocol.export(proxyFactory.getInvoker(ref, (Class) interfaceClass, local)); //本地暴露
    -> proxyFactory.getInvoker(ref, (Class) interfaceClass, local)
        -> extension = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension("javassist"); // SPI获取Adaptive
        -> extension.getInvoker(arg0, arg1, arg2)
        JavassistProxyFactory.java
            -> final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type); //创建一个Wapper,这个Wapper列举了所有对象的方法,减少了调用时反射的性能消耗
            -> return new AbstractProxyInvoker<T>(proxy, type, url) // AbstractProxyInvoker的inovke方法会把invocation的参数取出来调用wrapper来处理
 
    -> extension = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension("injvm"); //获取Injvm协议
    -> extension.export(arg0)
    -> ProtocolFilterWrapper.export(arg0) // Protocol有包装类 对应SPI的AOP
        -> 如果是注册中心,不处理
    <----> 不是则return protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER));
            -> buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER) //对Invoker进行包装一层filter
            ProtocolListenerWrapper.java
            -> ProtocolListenerWrapper.export
                -> 如果是注册中心,不处理
                -> Exporter<T> exporter = protocol.export(invoker);
                    InjvmProtocol.java
                    -> return new InjvmExporter<T>(invoker, invoker.getUrl().getServiceKey(), exporterMap) //目的:exporterMap.put(key, this) key=com.alibaba.dubbo.demo.DemoService, this=InjvmExporter
                -> List<ExporterListener> listeners = Collections.unmodifiableList(ExtensionLoader.getExtensionLoader(ExporterListener.class).getActivateExtension(invoker.getUrl(), Constants.EXPORTER_LISTENER_KEY)); //获取Export监听器
        <--------> return new ListenerExporterWrapper<T>(exporter, listeners);
 
-> exporters.add(exporter); //添加exporter
 

QA:
1.最后我们得到的exporter是一个什么结构?
 
2.记录下注册中心的URL结构,和暴露协议不同这里都是register协议,然后有个register=zookeeper这样
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值