美文网首页
netty源码分析(2)-初始化Channel

netty源码分析(2)-初始化Channel

作者: Jorgezhong | 来源:发表于2019-02-18 15:40 被阅读0次

    上一节分析了Channel的创建过程,回忆一下,其实newChannel()方法其实只是实例化了一个Channel对象,还未初始化成员变量以及一些列配置.

     @Override
        public T newChannel() {
            try {
                return clazz.newInstance();
            } catch (Throwable t) {
                throw new ChannelException("Unable to create Channel from class " + clazz, t);
            }
        }
    

    入口:initAndRegister() 在调用了newContext()之后紧接着又调用了 init()对channel进行了初始化的过程。以服务端为例,该方法由ServerBootstrap实现

    channel = channelFactory.newChannel();
    init(channel);
    
    • init(channel)

    初始化过程呢,先配置的是AbstractBootstrap的成员变量,这些成员变量会在初始化当中便启用。

        private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();
        private final Map<AttributeKey<?>, Object> attrs = new LinkedHashMap<AttributeKey<?>, Object>();
        private volatile ChannelHandler handler;
    

    而在子类ServerBootstrap中的定义的成员变量,则会作为连接器ServerBootstrapAcceptor的参数,在客户端与服务器建立新的连接的时候进行实例化,因此这部分成员变量的启用的时间是连接成功后启用。

        private final Map<ChannelOption<?>, Object> childOptions = new LinkedHashMap<ChannelOption<?>, Object>();
        private final Map<AttributeKey<?>, Object> childAttrs = new LinkedHashMap<AttributeKey<?>, Object>();
        private final ServerBootstrapConfig config = new ServerBootstrapConfig(this);
        private volatile EventLoopGroup childGroup;
        private volatile ChannelHandler childHandler;
    

    参数基本都来源于用户配置,例如:

     serverBootstrap.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class)
                        .option(ChannelOption.SO_REUSEADDR,true)
                        .childOption(ChannelOption.TCP_NODELAY, true)
                        .attr(AttributeKey.newInstance("attr"),"attr")
                        .childAttr(AttributeKey.newInstance("childAttr"),"childAttr")
                        .handler(new DataServerInitializer0())
                        .childHandler(new DataServerInitializer());
    
     @Override
        void init(Channel channel) throws Exception {
    
            //配置AbstractBootstrap.option
            final Map<ChannelOption<?>, Object> options = options0();
            synchronized (options) {
                setChannelOptions(channel, options, logger);
            }
    
            //配置AbstractBootstrap.attr
            final Map<AttributeKey<?>, Object> attrs = attrs0();
            synchronized (attrs) {
                for (Entry<AttributeKey<?>, Object> e: attrs.entrySet()) {
                    @SuppressWarnings("unchecked")
                    AttributeKey<Object> key = (AttributeKey<Object>) e.getKey();
                    channel.attr(key).set(e.getValue());
                }
            }
            //配置pipeline
            ChannelPipeline p = channel.pipeline();
            
            //获取ServerBootstrapAcceptor配置参数
            final EventLoopGroup currentChildGroup = childGroup;
            final ChannelHandler currentChildHandler = childHandler;
            
            final Entry<ChannelOption<?>, Object>[] currentChildOptions;
            final Entry<AttributeKey<?>, Object>[] currentChildAttrs;
            synchronized (childOptions) {
                currentChildOptions = childOptions.entrySet().toArray(newOptionArray(0));
            }
            synchronized (childAttrs) {
                currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(0));
            }
    
            p.addLast(new ChannelInitializer<Channel>() {
                @Override
                public void initChannel(final Channel ch) throws Exception {
                    final ChannelPipeline pipeline = ch.pipeline();
                    //配置AbstractBootstrap.handler
                    ChannelHandler handler = config.handler();
                    if (handler != null) {
                        pipeline.addLast(handler);
                    }
    
                    ch.eventLoop().execute(new Runnable() {
                        @Override
                        public void run() {
                            //配置ServerBootstrapAcceptor,剩下所有的handler都封装了
                            pipeline.addLast(new ServerBootstrapAcceptor(
                                    ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
                        }
                    });
                }
            });
        }
    

    相关文章

      网友评论

          本文标题:netty源码分析(2)-初始化Channel

          本文链接:https://www.haomeiwen.com/subject/jfpaeqtx.html