您的位置:首页 > 其它

dubbo 2标签解析 ServiceBean<T> 生产者服务暴漏过程

2017-07-03 18:15 387 查看
二、dubbo标签解析

com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler

public void init() {
   registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));

        registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));

        registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));

        registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));

        registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));

        registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));

        registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));

        registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));

        registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));

        registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));

    }

三、ServiceBean<T> 生产者服务暴漏过程,<dubbo:service>标签最终解析成了ServiceBean。

1、 ServiceConfig 的export方法为暴漏服务的方法。

    private void doExportUrls() {

        List<URL> registryURLs = loadRegistries(true);
//loadRegistries检查了注册中心,如果存在设置了URL的Protocol为registry
// url = url.addParameter(Constants.REGISTRY_KEY, url.getProtocol());
//可以配置多协议暴漏

        for (ProtocolConfig protocolConfig : protocols) {

            doExportUrlsFor1Protocol(protocolConfig, registryURLs);

        }

    }

2、 doExportUrlsFor1Protocol中

   Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));

   //生成了invoker,默认使用JavassistProxyFactory

   Exporter<?> exporter = protocol.export(invoker);

   exporters.add(exporter);

   

   这个protocol使用的是Adaptive的,而这个invoker.url.protocol为registry,所以实际会得到RegistryProtocol

   再加上wrapper则会得到ProtocolListenerWrapper->ProtocolFilterWrapper->RegistryProtocol

   

3、ProtocolListenerWrapper和ProtocolFilterWrapper在export方法中对registry类型的直接通过

   ProtocolFilterWrapper

   public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {

        if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {

            return protocol.export(invoker);

        }

        return protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER));

    }

   到了RegistryProtocol的export

   //export invoker

   final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker);

   

   doLocalExport中

   final Invoker<?> invokerDelegete = new InvokerDelegete<T>(originInvoker, getProviderUrl(originInvoker));

   exporter = new ExporterChangeableWrapper<T>((Exporter<T>)protocol.export(invokerDelegete), originInvoker);

   bounds.put(key, exporter);

   

   getProviderUrl(originInvoker)通过invoker的url 获取 providerUrl的地址,这时候url的protocol就不是registry了,

   而是具体的协议,比如dubbo

   那么后面的protocol.export就会使用DubboProtocol,当然同样加上了wrapper,这两个wrapper会在调用过程中加上

   listener和filter链,链的最后就是invoker

   

4、DubboProtocol的export

   DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);

   ....

   openServer(url)->createServer(url);

   根据具体协议启动服务器,监听端口

5、Exchangers.bind->Transporters.bind->Server

   server = Exchangers.bind(url, requestHandler);

   HeaderExchanger的bind

    public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {

        return new HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler))));

    }

Transporters的bind  return getTransporter().bind(url, handler);
这里的Transporter使用的是自适应的,那么会根据配置或者默认使用NettyTransporter

6、NettyTransporter.bind->NettyServer(url, listener);

   NettyServer里面的doOpen就是netty启动服务端的过程。

   

7、回到RegistryProtocol的export,在暴漏完invoker后,接着去注册中心注册了服务提供者

   使用zookeeper则会注册地址/dubbo/interfaceClass/providers/{providerUrl}存储生成者的ip,端口等,供消费者订阅获取使用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: