netty中pipeline分析_1(初始化)

概述

  • pipeline, 顾名思义, 就是管道的意思, 事件在pipeline中传输, 用户可以中断事件, 添加自己的事件处理逻辑, 可以直接将事件中断不再往下传输, 同样可以改变管道的流向, 传递其他事件。
  • 事件通常分为两种, 一是inBound入站事件, 另一种是outBound出站事件。
    • inBound事件, 顾名思义, 就是从另一端流向自己的事件, 比如读事件, 连接完成事件等等。
    • outBound, 是从自己流向另一端的事件, 比如连接事件, 写事件, 刷新缓冲区事件等等。
  • 事件是通过handler对象进行处理的, 里面封装着事件的处理逻辑.而每个handler, 是由HandlerContext进行包装的, 里面封装了对事件传输的操作。
  • 每一个channel绑定一个pipeline, 那么pipelinehandler又是什么关系?
    • pipeline可以理解成是一个双向链表, 只是存放的并不是数据而是HandlerContext, 而HandlerContext又包装了handler, 事件传输时, 从头结点(或者尾节点)开始, 找到下一个HandlerContext, 执行Handler的业务逻辑, 然后再继续往下走, 直到执行到尾节点(或者头结点, 反向)为止。
      在这里插入图片描述

继承关系

在这里插入图片描述

  • 如果属于ChannelInboundHandler的子类, 则属于Inbound类型的handler
  • 如果属于ChannelOutboundHandler的子类, 则属于Outbound类型的handler

pipeline的创建

回到AbstractChannel的构造方法

protected AbstractChannel(Channel parent) {
    this.parent = parent;
    id = newId();
    unsafe = newUnsafe();
    pipeline = newChannelPipeline();
}

newChannelPipeline()

protected DefaultChannelPipeline newChannelPipeline() {
	//传入当前channel
    return new DefaultChannelPipeline(this);
}
DefaultChannelPipeline的构造方法
protected DefaultChannelPipeline(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;
}
  • 保存了当前channel
  • 保存了两个属性succeededFuture, voidPromise, 这两个属性是Future相关的内容, 之后会讲到。
  • 初始化了两个节点, head节点和tail节点, 在pipeline中代表头结点和尾节点
new TailContext(this)

尾结点的构建

final class TailContext extends AbstractChannelHandlerContext implements ChannelInboundHandler {
    TailContext(DefaultChannelPipeline pipeline) {
        //inbound处理器
        super(pipeline, null, TAIL_NAME, true, false);
        //将当前节点设置为已添加, head和tail.....
        setAddComplete();
    }

    //自身也是handler
    @Override
    public ChannelHandler handler() {
        return this;
    }
     
    //方法省略
}    
  • 这个是DefualtPipline的内部类, 首先看其继承了AbstractChannelHandlerContext类, 说明自身是个HandlerContext, 同时也实现ChannelInboundHander接口, 并且其中的handler()方法返回了自身, 说明自身也是handler, 而实现ChannelInboundHander, 说明自身只处理Inbound事件。
  • 构造方法中, 调用了父类的构造器, 看其中参数
    • pipeline是自身所属的pipeline
    • executor为null
    • TAIL_NAME是当前handler, 也就是自身的命名
    • true代表自身是inboundHandler
    • fasle代表自身不是outboundHandler

AbstractChannelHandlerContext的构造方法

AbstractChannelHandlerContext(DefaultChannelPipeline pipeline, EventExecutor executor, String name, 
                              boolean inbound, boolean outbound) {
    //名字
    this.name = ObjectUtil.checkNotNull(name, "name");
    //pipeline
    this.pipeline = pipeline;
    //线程处理器
    this.executor = executor;
    //事件标识
    this.inbound = inbound;
    this.outbound = outbound;
    ordered = executor == null || executor instanceof OrderedEventExecutor;
}
  • pipeline为自身绑定的pipeline
  • exeutor是线程执行器, 这里为空
  • inboundoutbound是事件标志, 这里分别是truefalse, 也就是自身属于inboundHnadler而不属于outboundHandler
new HeadContext(this)

头结点的构建

final class HeadContext extends AbstractChannelHandlerContext
        implements ChannelOutboundHandler, ChannelInboundHandler {

    private final Unsafe unsafe;

    HeadContext(DefaultChannelPipeline pipeline) {
        super(pipeline, null, HEAD_NAME, false, true);
        unsafe = pipeline.channel().unsafe();
        setAddComplete();
    }

    @Override
    public ChannelHandler handler() {
        return this;
    }
}
  1. 看过了tail节点, head节点就不难理解, 同样继承了AbstractChannelHandlerContext, 说明自身是一个HandlerContext, 与tail不同的是, 这里实现了ChannelOutboundHandler接口和ChannelOutboundHandler接口, 说明其既能处理inbound事件也能处理outbound的事件, handler方法返归自身, 说明自身是一个handler
  2. 在构造方法中初始化了一个Unsafe类型的成员变量, 是通过自身绑定的channel拿到的, 说明这个类中可以进行对channel的读写操作。这里同样调用了父类的构造方法, 不同的是, 这里inbound参数传入了false, 而outbound参数传入了true, 这里说明这里标志的事件是outbound事件。同学们可能疑惑, 为什么同时执行ChannelOutboundHandler接口和ChannelOutboundHandler接口,但是标志的事件不同?
  3. 其实这两个地方应用的场景是不同的, 继承ChannelOutboundHandlerChannelOutboundHandler, 说明其既能处理inbound事件也能处理outBound的事件, 但是只有outbound属性为true说明自身是一个outboundhandler, 是一个可以处理inbound事件的outboundhandler(估计被绕晕了), 这两种handler主要是保证在事件传输中保证事件的单方向流动, 在后面事件传输我们能领会到。

AbstractChannelHandlerContext的构造方法

AbstractChannelHandlerContext(DefaultChannelPipeline pipeline, EventExecutor executor, String name, 
                              boolean inbound, boolean outbound) {
    //名字
    this.name = ObjectUtil.checkNotNull(name, "name");
    //pipeline
    this.pipeline = pipeline;
    //线程处理器
    this.executor = executor;
    //事件标识
    this.inbound = inbound;
    this.outbound = outbound;
    ordered = executor == null || executor instanceof OrderedEventExecutor;
}

AbstractChannelHandlerContext的构建和尾结点构建时相同

回到DefaultChannelPipeline的构造方法
protected DefaultChannelPipeline(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;
}

介绍完了new TailContext(this)new HeadContext(this),继续分析

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

tail节点和head节点中的nextprev属性, 其实是其父类AbstractChannelHandlerContext, 每一个handlerContext都拥有这两个属性, 代表自身的下一个节点和上一个节点, 因为我们概述中介绍过pipeline其实是一个双向链表, 所以其中每一个节点必须有指向其他节点的指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值