ChannelPipeline采用责任链模式设计。在责任链模式中,由每个对象对其下个对象的引用而连接起来的一条链,请求在这条链上传递,知道链上某个对象处理该请求并中止传递。发送请求者并不知道链上的哪个对象处理该请求,从而使得系统可以在不影响发送端的情况下动态的重新分配责任。
DefaultChannelPipeline
Handler链的默认实现类,维护了链中的头结点和尾结点,DefaultChannelPipeline对象在构建时,就会创建头结点和尾结点对象。之后添加的Handler都会添加到两者中间,addLast会添加到尾结点的前面,addFirst会添加到头结点的后面。在添加时可以给Handler指定名称,如果名称有重复会抛出异常。
Handler分为两种,一种是实现ChannelInboundHandler接口的,一种是实现ChannelOutboundHandler接口的。ChannelInboundHandler接口主要处理从外到内的请求,将远端操作通知本地(比如注册,激活,读等),从Head结点开始传递,直到tail结点。而ChannelOutboundHandler接口主要处理从内到外的操作,将本地操作通知远端(比如连接,绑定,写)等,从tail结点开始传递,到Head结点后转由unsafe类进行真正处理。1
2tail = new TailContext(this); // tail实现了ChannelInboundHandler接口
head = new HeadContext(this); // head实现了ChannelOutboundHandler和ChannelInboundHandler接口
上文讲到的ServerBootstrapAcceptor类,就是一个ChannelInboundHandlerAdapter类型的Handler。所以当连接完成对上层发出通知时,通知从Head结点开始传递,到达ServerBootstrapAcceptor中处理并中止传递。
AbstractChannelHandlerContext
AbstractChannelHandlerContext是对ChannelHandler的一个包装类,Pipeline中真正的对象实际上是AbstractChannelHandlerContext。在AbstractChannelHandlerContext中维护了next、prev属性,所以这是一个双向链表结构。1
2
3volatile AbstractChannelHandlerContext next; // 下个结点
volatile AbstractChannelHandlerContext prev; // 上个结点
private final ChannelHandler handler; // 真正Handler对象
接下来讲到的编解码器也是根据Pipeline来实现的。