6_netty_ChannelPipeline

在上一篇实例化NioServerSocketChannel中,

    protected DefaultChannelPipeline newChannelPipeline() {
        return new DefaultChannelPipeline(this);
    }

看看DefaultChannelPipeline的继续结构,并不复杂。


    protected DefaultChannelPipeline(Channel channel) {
        //设置channel
        this.channel = ObjectUtil.checkNotNull(channel, "channel");
        succeededFuture = new SucceededChannelFuture(channel, null);
        voidPromise =  new VoidChannelPromise(channel, true);

        tail = new TailContext(this);
        head = new HeadContext(this);

        head.next = tail;
        tail.prev = head;
    }

TailContext和HeadContext都是DefaultChannelPipline的内部类。



 HeadContext(DefaultChannelPipeline pipeline) {
          //设置属性
            super(pipeline, null, HEAD_NAME, false, true);
            unsafe = pipeline.channel().unsafe();
            setAddComplete();
        }

第四个参数表示inbound,第五个表示outbound,这里的HeadContext是outbound的,那么表示处理出站的handler。相反的TailContext是处理入站的handler。
示例代码中都是addLast,我们就先看看addLast方法。

    public final ChannelPipeline addLast(ChannelHandler... handlers) {
        return addLast(null, handlers);
    }
    public final ChannelPipeline addLast(EventExecutorGroup executor, ChannelHandler... handlers) {
        if (handlers == null) {
            throw new NullPointerException("handlers");
        }

        for (ChannelHandler h: handlers) {
            if (h == null) {
                break;
            }
            addLast(executor, null, h);
        }

        return this;
    }

    public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
        final AbstractChannelHandlerContext newCtx;
        synchronized (this) {
            //检查是否添加过这个handler,通过added属性判断
            checkMultiplicity(handler);
          //新建DefaultChannelHandlerContext类
            newCtx = newContext(group, filterName(name, handler), handler);
          //将包装后的DefaultChannelHandlerContext类加入双向链表
          //将会被放在headcontext和tailcontext之间
            addLast0(newCtx);

            // If the registered is false it means that the channel was not registered on an eventloop yet.
            // In this case we add the context to the pipeline and add a task that will call
            // ChannelHandler.handlerAdded(...) once the channel is registered.
            //判断channel是否注册过eventloop,如果没有需要添加任务,并在
            //channel注册的时候调用ChannelHnadler.handlerAdded()方法
            if (!registered) {
                newCtx.setAddPending();
                callHandlerCallbackLater(newCtx, true);
                return this;
            }

            EventExecutor executor = newCtx.executor();
            if (!executor.inEventLoop()) {
                newCtx.setAddPending();
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        callHandlerAdded0(newCtx);
                    }
                });
                return this;
            }
        }
        callHandlerAdded0(newCtx);
        return this;
    }

上述将添加任务后,会在bind的后续代码中register0方法内执行pipeline.invokeHandlerAddedIfNeeded(),最后一步就会执行对应的ChannelInitializer的initChannel方法。

总结下:

  1. 在创建channnel的时候,会同时创建pipeline对象进行绑定
  2. pipeline是一个双端队列,初始化的时候头会新建好head和tail,前者是outbound,后者是inbound。

你可能感兴趣的:(6_netty_ChannelPipeline)