注册顺序
ch.pipeline().addLast(new InboundHandler1());
ch.pipeline().addLast(new InboundHandler2());
ch.pipeline().addLast(new OutboundHandler1());
ch.pipeline().addLast(new OutboundHandler2());
ctx.fireChannelRead()入站时找 InboundHandler最终会调用如下方法:
private AbstractChannelHandlerContext findContextInbound() {
AbstractChannelHandlerContext ctx = this;
do {
ctx = ctx.next;
} while (!ctx.inbound);
return ctx;
}
控制台输出如下:
并不会出现OutboundHandler的数据,理论上调用了ctx.writeAndFlush()方法将数据传给下一个handler了,也就是OutboundHandler1,继续看ctx.writeAndFlush()底层方法,发现它调用了write()方法
write()方法调用了findContextOutbound()方法,发现它这里是用当前引用向前找OutboundHandler,当前引用是InboundHandler2,顿时茅塞顿开!
InboundHandler和OutboundHandler都是一个双向链表的结构,入站时找InboundHandler时引用ctx指到了InboundHandler2,出站时找OutboundHandler引用还是指到了InboundHandler2,再向前找当然找不到OutboundHandler,所以就不会执行OutboundHandler1和OutboundHandler2。