前面看了channel定義,以及接口定義,可知道實作類。
* I/O Request
* via {@link Channel} or
* {@link ChannelHandlerContext}
* |
* +---------------------------------------------------+---------------+
* | ChannelPipeline | |
* | \|/ |
* | +----------------------------------------------+----------+ |
* | | ChannelHandler N | |
* | +----------+-----------------------------------+----------+ |
* | /|\ | |
* | | \|/ |
* | +----------+-----------------------------------+----------+ |
* | | ChannelHandler N-1 | |
* | +----------+-----------------------------------+----------+ |
* | /|\ . |
* | . . |
* | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
* | [method call] [method call] |
* | . . |
* | . \|/ |
* | +----------+-----------------------------------+----------+ |
* | | ChannelHandler 2 | |
* | +----------+-----------------------------------+----------+ |
* | /|\ | |
* | | \|/ |
* | +----------+-----------------------------------+----------+ |
* | | ChannelHandler 1 | |
* | +----------+-----------------------------------+----------+ |
* | /|\ | |
* +---------------+-----------------------------------+---------------+
* | \|/
* +---------------+-----------------------------------+---------------+
* | | | |
* | [ Socket.read() ] [ Socket.write() ] |
* | |
* | Netty Internal I/O Threads (Transport Implementation) |
* +-------------------------------------------------------------------+
在看下接口方法
ChannelPipeline 主要是 inbound和outbound方法
inbound方法一般是内部定義的模闆方法,繼承實作之後就期待調用即可
outbound方法一般是對方提供api接口,比如bind connect read write等
DefaultChannelPipeline
然後我們看下channelPipeline的實作類,如何構造pipe的
final AbstractChannel channel;
final AbstractChannelHandlerContext head;
final AbstractChannelHandlerContext tail;
private final Map<String, AbstractChannelHandlerContext> name2ctx =
new HashMap<String, AbstractChannelHandlerContext>(4);
/**
* @see #findInvoker(EventExecutorGroup)
*/
private Map<EventExecutorGroup, ChannelHandlerInvoker> childInvokers;
DefaultChannelPipeline(AbstractChannel channel) {
if (channel == null) {
throw new NullPointerException("channel");
}
this.channel = channel;
tail = new TailContext(this);
head = new HeadContext(this);
head.next = tail;
tail.prev = head;
}
關鍵的兩個類tailContext和headcontext,這樣的話就扯出我們下一個接口 ChannelHandler