Dubbo-聊聊通信模块设计( 五 )


    private Codec2 codec;    private int connectTimeout;    public AbstractEndpoint(URL url, ChannelHandler handler) {        //调用父类        super(url, handler);        //根据URL中的codec参数值,确定此处具体的Codec2实现类        this.codec = getChannelCodec(url);        //设置connectTimeout        this.connectTimeout = url.getPositiveParameter(Constants.CONNECT_TIMEOUT_KEY, Constants.DEFAULT_CONNECT_TIMEOUT);    }    protected static Codec2 getChannelCodec(URL url) {        //获取URL协议        String codecName = url.getProtocol();        //判断有没有该扩展名        if (ExtensionLoader.getExtensionLoader(Codec2.class).hasExtension(codecName)) {            //通过ExtensionLoader加载具体实现类            return ExtensionLoader.getExtensionLoader(Codec2.class).getExtension(codecName);        } else {            //没有匹配到从扩展类进行加载            return new CodecAdapter(ExtensionLoader.getExtensionLoader(Codec.class)                    .getExtension(codecName));        }    }此外该接口实现Resetable接口,该接口内部只有一个reset方法,该方法通过获取URL参数信息,重置了connectTimeout的信息以及Codec2的信息 。
AbstractServerAbstractServer是对服务端的抽象,该抽象类实现AbstractEndpoint和RemotingServer,该抽象类内部有五个核心属性,localAddress、bindAddress这两个属性都是在URL参数中获取,表示Server本地的地址以及绑定的地址 , 默认两个值是一致的,accepts表示是Server最大的连接次数,默认是0,表述没有限制,executorRepository、executor线程池相关的属性,executorRepository负责管理线程池,executor表示当前服务管理的线程池 。
    //当前服务关联的线程池    ExecutorService executor;    //本机地址    private InetSocketAddress localAddress;    //绑定地址    private InetSocketAddress bindAddress;    //最大连接数    private int accepts;    //管理线程池    private ExecutorRepository executorRepository = ExtensionLoader.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();AbstractServer初始化也就是在构造函数中完成初始化的,然后通过调用其抽象方法doOpen实现启动服务器 。
    public AbstractServer(URL url, ChannelHandler handler) throws RemotingException {        //调用父类        super(url, handler);        //从URL获取本地地址        localAddress = getUrl().toInetSocketAddress();        String bindIp = getUrl().getParameter(Constants.BIND_IP_KEY, getUrl().getHost());        int bindPort = getUrl().getParameter(Constants.BIND_PORT_KEY, getUrl().getPort());        if (url.getParameter(ANYHOST_KEY, false) || NetUtils.isInvalidLocalHost(bindIp)) {            bindIp = ANYHOST_VALUE;        }        //绑定地址        bindAddress = new InetSocketAddress(bindIp, bindPort);        //连接数        this.accepts = url.getParameter(ACCEPTS_KEY, DEFAULT_ACCEPTS);        try {            //调用该抽象方法启动服务            doOpen();            if (logger.isInfoEnabled()) {                logger.info("Start " + getClass().getSimpleName() + " bind " + getBindAddress() + ", export " + getLocalAddress());            }        } catch (Throwable t) {            throw new RemotingException(url.toInetSocketAddress(), null, "Failed to bind " + getClass().getSimpleName()                    + " on " + getLocalAddress() + ", cause: " + t.getMessage(), t);        }        //创建该服务对应的线程池        executor = executorRepository.createExecutorIfAbsent(url);    }

推荐阅读