zoukankan      html  css  js  c++  java
  • dubbo源码解析(五) DubboProtocol

    DubboProtocol 这个类继承自AbstractProtocol,实现了Protocol接口,也就是实现了export和refer方法

    首先看一下export方法

    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
            URL url = invoker.getUrl();
            
            // export service.
            String key = serviceKey(url);
            DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);
            exporterMap.put(key, exporter);
            
            //export an stub service for dispaching event
            Boolean isStubSupportEvent = url.getParameter(Constants.STUB_EVENT_KEY,Constants.DEFAULT_STUB_EVENT);
            Boolean isCallbackservice = url.getParameter(Constants.IS_CALLBACK_SERVICE, false);
            if (isStubSupportEvent && !isCallbackservice){
                String stubServiceMethods = url.getParameter(Constants.STUB_EVENT_METHODS_KEY);
                if (stubServiceMethods == null || stubServiceMethods.length() == 0 ){
                    if (logger.isWarnEnabled()){
                        logger.warn(new IllegalStateException("consumer [" +url.getParameter(Constants.INTERFACE_KEY) +
                                "], has set stubproxy support event ,but no stub methods founded."));
                    }
                } else {
                    stubServiceMethodsMap.put(url.getServiceKey(), stubServiceMethods);
                }
            }
    
            openServer(url);
            
            return exporter;
        }

    这个方法首先从invoker中取出url,然后用这个url生成一个key。再用这个key和传入的invoker加上类本身的属性变量exporterMap生成了一个DubboExporter

    后面则通过openServer(url)实现对该url的监听。并返回exporter对象。

    再接着看openServer方法

    private void openServer(URL url) {
            // find server.
            String key = url.getAddress();
            //client 也可以暴露一个只有server可以调用的服务。
            boolean isServer = url.getParameter(Constants.IS_SERVER_KEY,true);
            if (isServer) {
                ExchangeServer server = serverMap.get(key);
                if (server == null) {
                    serverMap.put(key, createServer(url));
                } else {
                    //server支持reset,配合override功能使用
                    server.reset(url);
                }
            }
        }

    这个方法比较简单,首先判断当前的url是不是server方法,如果是server方法从缓存中取ExchangeServer,如果取不到则通过createServer方法创建新的server并放入缓存中。

    接着看createServer方法

    private ExchangeServer createServer(URL url) {
            //默认开启server关闭时发送readonly事件
            url = url.addParameterIfAbsent(Constants.CHANNEL_READONLYEVENT_SENT_KEY, Boolean.TRUE.toString());
            //默认开启heartbeat
            url = url.addParameterIfAbsent(Constants.HEARTBEAT_KEY, String.valueOf(Constants.DEFAULT_HEARTBEAT));
            String str = url.getParameter(Constants.SERVER_KEY, Constants.DEFAULT_REMOTING_SERVER);
    
            if (str != null && str.length() > 0 && ! ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str))
                throw new RpcException("Unsupported server type: " + str + ", url: " + url);
    
            url = url.addParameter(Constants.CODEC_KEY, Version.isCompatibleVersion() ? COMPATIBLE_CODEC_NAME : DubboCodec.NAME);
            ExchangeServer server;
            try {
                server = Exchangers.bind(url, requestHandler);
            } catch (RemotingException e) {
                throw new RpcException("Fail to start server(url: " + url + ") " + e.getMessage(), e);
            }
            str = url.getParameter(Constants.CLIENT_KEY);
            if (str != null && str.length() > 0) {
                Set<String> supportedTypes = ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions();
                if (!supportedTypes.contains(str)) {
                    throw new RpcException("Unsupported client type: " + str);
                }
            }
            return server;
        }

    最主要的代码server = Exchangers.bind(url, requestHandler);

    将url和requestHandler进行绑定,绑定之后得到一个server返回。

    这样就完成了一个接口的export

    接下来看一下另外一个方法refer

    public <T> Invoker<T> refer(Class<T> serviceType, URL url) throws RpcException {
            // create rpc invoker.
            DubboInvoker<T> invoker = new DubboInvoker<T>(serviceType, url, getClients(url), invokers);
            invokers.add(invoker);
            return invoker;
        }

    这个方法只是new了一个DubboInvoker,并且将invoker放入缓存中,返回invoker对象。

  • 相关阅读:
    How to create Ubuntu Image with Linaro Image Tools
    linux little tool
    Firefly-RK3288
    tensorflow 出现KeyError: 'tulips\8689672277_b289909f97_n.jpg'报错
    开发中涉及的框架与工具
    这三年被分布式坑惨了,曝光十大坑 【转载】
    C#动态编译及执行代码
    cron表达式可视化编辑页面
    AVPacket相关函数介绍
    ffmpeg 重要函数介绍
  • 原文地址:https://www.cnblogs.com/liguangming/p/10160621.html
Copyright © 2011-2022 走看看