Netty 使用ChannelPipeline来实现拦截链路调用
* I/O Request
* via {@link Channel} or
* {@link ChannelHandlerContext}
* |
* +---------------------------------------------------+---------------+
* | ChannelPipeline | |
* | |/ |
* | +---------------------+ +-----------+----------+ |
* | | Inbound Handler N | | Outbound Handler 1 | |
* | +----------+----------+ +-----------+----------+ |
* | /| | |
* | | |/ |
* | +----------+----------+ +-----------+----------+ |
* | | Inbound Handler N-1 | | Outbound Handler 2 | |
* | +----------+----------+ +-----------+----------+ |
* | /| . |
* | . . |
* | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
* | [ method call] [method call] |
* | . . |
* | . |/ |
* | +----------+----------+ +-----------+----------+ |
* | | Inbound Handler 2 | | Outbound Handler M-1 | |
* | +----------+----------+ +-----------+----------+ |
* | /| | |
* | | |/ |
* | +----------+----------+ +-----------+----------+ |
* | | Inbound Handler 1 | | Outbound Handler M | |
* | +----------+----------+ +-----------+----------+ |
* | /| | |
* +---------------+-----------------------------------+---------------+
* | |/
* +---------------+-----------------------------------+---------------+
* | | | |
* | [ Socket.read() ] [ Socket.write() ] |
* | |
* | Netty Internal I/O Threads (Transport Implementation) |
* +-------------------------------------------------------------------+
例如 fireChannelRead为例
1.1 AbstractChannelHandlerContext#fireChannelRead
1 @Override 2 public ChannelHandlerContext fireChannelRead(final Object msg) {
//findContextInbound方法负责寻找next Context 3 invokeChannelRead(findContextInbound(), msg); 4 return this; 5 }
1.2 AbstractChannelHandlerContext#invokeChannelRead(io.netty.channel.AbstractChannelHandlerContext, java.lang.Object)
1 static void invokeChannelRead(final AbstractChannelHandlerContext next, final Object msg) { 2 ObjectUtil.checkNotNull(msg, "msg"); 3 EventExecutor executor = next.executor(); 4 if (executor.inEventLoop()) { 5 next.invokeChannelRead(msg); 6 } else { 7 executor.execute(new Runnable() { 8 @Override 9 public void run() { 10 next.invokeChannelRead(msg); 11 } 12 }); 13 } 14 }
1.3 AbstractChannelHandlerContext#invokeChannelRead(java.lang.Object)
1 private void invokeChannelRead(Object msg) { 2 if (invokeHandler()) { 3 try {//Context中handler实际处理逻辑 4 ((ChannelInboundHandler) handler()).channelRead(this, msg); 5 } catch (Throwable t) { 6 notifyHandlerException(t); 7 } 8 } else { 9 fireChannelRead(msg); 10 } 11 }
1.4 以LoggingHandler为例 io.netty.handler.logging.LoggingHandler#channelRead
1 @Override 2 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//这一行代码 是LoggerHandler的实际处理逻辑 3 logMessage(ctx, "RECEIVED", msg);
//这一行代码是链路调用的关键,调用1.1,形成链路调用 4 ctx.fireChannelRead(msg); 5 }
参考 https://blog.csdn.net/zxhoo/article/details/17264263