1 Pipeline设计原理
在Netty中每个Channel都有且仅有一个ChannelPipeline与之对应,它们的组成关系如下图:

通过上图可以看到,一个Channel包含了一个ChannelPipeline,而ChannelPipeline中又维护了一个由ChannelHandlerContext组成的双向链表。这个链表的头是HeadContext,链表的尾是TailContext,并且每个ChannelHandlerContext又关联着一个ChannelHandler。
通过分析代码,已经知道了一个Channel初始化的基本过程,下面在回顾一下。AbstractChannel构造器的代码如下:
protected AbstractChannel(Channel parent) {
this.parent = parent;
id = newId();
unsafe = newUnsafe();
pipeline = newChannelPipeline();
}
AbstractChannel有一个pipeline属性,在构造器中会把它初始化为DefaultChannelPipeline的实例。这里的代码就印证了这一点:每个Channel都有一个ChannelPipeline。来看一下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;
}
在DefaultChannelPipeline构造器中,首先将与之关联的Channel保存到属性channel中。然后实例化两个ChannelHandlerContext:一个是HeadContext实例Head,另一个是TailContext实例Tail。接着将Head和Tail互相指向,构成一个双向链表。
特别注意的是:在开始的示意图中,Head和Tail并没有包含ChannelHandler,这是因为HeadContext和TailContext继承于AbstractChannelHandlerContext的同时,也实现了ChannelHandler接口,所以它们有Context和Handler的双重属性。
2 ChannelPipeline初始化
下面看一下ChannelPipeline的初始化具体做了哪些工作。先回顾一下,在实例化一个Channel时,会伴随着一个ChannelPipeline的实例化,并且此Channel会与这个ChannelPipeline相互关联,这一点可以通过NioEventLoop的父类AbstractChannel的构造器予以佐证,代码如下:
protected AbstractChannel(Channel parent) {
this.parent = parent;
id = newId();
unsafe = newUnsafe();
pipeline = newChannelPipeline();
}
当实例化一个NioSocketChannel时,其pipeline属性就是新创建的DefaultChannelPipeline对象,再来回顾一下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;
}
上面代码中的Head实现了ChannelInboundHandler接口,而Tail实现了ChannelOutboundHandler接口,因此可以说Head和Tail就是ChannelHandler,又是ChannelHandlerContext。
3 ChannelInitializer的添加
前面分析过Channel的组成,最开始的时候ChannelPipeline中含有两个ChannelHandlerContext,但是此时的Pipeline并不能实现特定的功

最低0.47元/天 解锁文章
2033

被折叠的 条评论
为什么被折叠?



