NOTE

2.86 2.初始化channel

1. 要分析的代码 2. 获取channel pipeline并加入一个ChannelInitializer 如上的代码最关键的在于获取当前channel对应的pipeline,并加入了一个ChannelInitializer。 而在这个ChannelInitializer中,把我们自己在 Serv

Java创建于 更新于 historical

这是历史学习笔记,可能存在过时或不完整的理解。

1. 要分析的代码

init(channel);

2. 获取channel pipeline并加入一个ChannelInitializer

void init(Channel channel) throws Exception {
	//设置options
    final Map<ChannelOption<?>, Object> options = options0();
    synchronized (options) {
        setChannelOptions(channel, options, logger);
    }
	//设置attrs
    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());
        }
    }

	//获取channel关联的pipeline
    ChannelPipeline p = channel.pipeline();

    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(childOptions.size()));
    }
    synchronized (childAttrs) {
        currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(childAttrs.size()));
    }

	//把ChannelInitializer加入到pipeline中
    p.addLast(new ChannelInitializer<Channel>() {
    	//后续某个阶段【2.实际注册】会回调这个initChannel方法
        @Override
        public void initChannel(final Channel ch) throws Exception {
            final ChannelPipeline pipeline = ch.pipeline();
        	//1.从而将我们自己定义的ChannelHandler加入pipeline中
            ChannelHandler handler = config.handler();
            if (handler != null) {
                pipeline.addLast(handler);
            }

            ch.eventLoop().execute(new Runnable() {
                @Override
                //2.将ServerBootstrapAcceptor加入pipeline中
                public void run() {
                    pipeline.addLast(new ServerBootstrapAcceptor(
                            ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
                }
            });
        }
    });
}

如上的代码最关键的在于获取当前channel对应的pipeline,并加入了一个ChannelInitializer。 而在这个ChannelInitializer中,把我们自己在ServerBootstrap中设置的handler添加在pipeline中,并且最后添加了一个ServerBootstrapAcceptor