ChannelPipeline在Netty中是用来处理请求的责任链,默认实现是DefaultChannelPipeline,其构造方法如下:
private final Channel channel;
private final ChannelFuture succeededFuture;
private final VoidChannelPromise voidPromise;
final AbstractChannelHandlerContext head;
final AbstractChannelHandlerContext tail; protected DefaultChannelPipeline(Channel channel) {
this.channel = (Channel)ObjectUtil.checkNotNull(channel, "channel");
this.succeededFuture = new SucceededChannelFuture(channel, (EventExecutor)null);
this.voidPromise = new VoidChannelPromise(channel, true);
this.tail = new DefaultChannelPipeline.TailContext(this);
this.head = new DefaultChannelPipeline.HeadContext(this);
this.head.next = this.tail;
this.tail.prev = this.head;
}
ChannelPipeline和Channel是一一对应关系,一个Channel绑定一条ChannelPipeline责任链
succeededFuture 和voidPromise用来处理异步操作
AbstractChannelHandlerContext 是持有请求的上下文对象,其和ChannelHandler是对应关系(在使用Sharable注解的情况下,不同的AbstractChannelHandlerContext 还可以对应同一个ChannelHandler),ChannelPipeline责任链
处理的就AbstractChannelHandlerContext ,再将最后的AbstractChannelHandlerContext 交给ChannelHandler去做正真的逻辑处理
AbstractChannelHandlerContext构造方法如下:
private final String name;
private final DefaultChannelPipeline pipeline;
final EventExecutor executor;
private final boolean inbound;
private final boolean outbound;
private final boolean ordered;
volatile AbstractChannelHandlerContext next;
volatile AbstractChannelHandlerContext prev; AbstractChannelHandlerContext(DefaultChannelPipeline pipeline, EventExecutor executor, String name, boolean inbound, boolean outbound) {
this.name = (String)ObjectUtil.checkNotNull(name, "name");
this.pipeline = pipeline;
this.executor = executor;
this.inbound = inbound;
this.outbound = outbound;
this.ordered = executor == null || executor instanceof OrderedEventExecutor;
}
name是AbstractChannelHandlerContext的名称,pipeline就是上面说的ChannelPipeline;executor是用来进行异步操作的,默认使用的是在前面博客中说过的NioEventLoop (Netty中NioEventLoopGroup的创建源码分析)
inbound 和outbound 代表两种请求处理方式,对应Netty中的I/O操作,若是inbound则处理Input操作,由ChannelPipeline从head 开始向后遍历链表,并且只处理ChannelInboundHandler类型的AbstractChannelHandlerContext;若是outbound 则处理Output操作,由ChannelPipeline从tail开始向前遍历链表,并且只处理ChannelOutboundHandler类型的AbstractChannelHandlerContext;
ordered 是判断是否需要提供executor。
由next和prev成员可以知道,ChannelPipeline维护的是一条AbstractChannelHandlerContext的双向链表
其头节点head和尾节点tail分别默认初始化了HeadContext和TailContext
HeadContext的构造:
final class HeadContext extends AbstractChannelHandlerContext implements ChannelOutboundHandler, ChannelInboundHandler {
private final Unsafe unsafe; HeadContext(DefaultChannelPipeline pipeline) {
super(pipeline, (EventExecutor)null, DefaultChannelPipeline.HEAD_NAME, false, true);
this.unsafe = pipeline.channel().unsafe();
this.setAddComplete();
}
}
其中setAddComplete是由AbstractChannelHandlerContext实现的:
final void setAddComplete() {
int oldState;
do {
oldState = this.handlerState;
} while(oldState != 3 && !HANDLER_STATE_UPDATER.compareAndSet(this, oldState, 2)); }
handlerState表示AbstractChannelHandlerContext对应的ChannelHandler的状态,有一下几种:
private static final int ADD_PENDING = 1;
private static final int ADD_COMPLETE = 2;
private static final int REMOVE_COMPLETE = 3;
private static final int INIT = 0;
private volatile int handlerState = 0;
handlerState初始化默认是INIT状态。
HANDLER_STATE_UPDATER是一个原子更新器:
private static final AtomicIntegerFieldUpdater<AbstractChannelHandlerContext> HANDLER_STATE_UPDATER = AtomicIntegerFieldUpdater.newUpdater(AbstractChannelHandlerContext.class, "handlerState");
所以setAddComplete方法,就是通过CAS操作,将handlerState状态更新为ADD_COMPLETE
TailContext的构造:
final class TailContext extends AbstractChannelHandlerContext implements ChannelInboundHandler {
TailContext(DefaultChannelPipeline pipeline) {
super(pipeline, (EventExecutor)null, DefaultChannelPipeline.TAIL_NAME, true, false);
this.setAddComplete();
}
}
和HeadContext一样,将handlerState状态更新为ADD_COMPLETE
结合官方给出的ChannelPipeline的图示更容易理解:
I/O Request
via Channel or
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) |
+-------------------------------------------------------------------+
下面对一些主要方法分析:
addFirst方法,有如下几种重载:
public final ChannelPipeline addFirst(ChannelHandler handler) {
return this.addFirst((String)null, (ChannelHandler)handler);
} public final ChannelPipeline addFirst(String name, ChannelHandler handler) {
return this.addFirst((EventExecutorGroup)null, name, handler);
} public final ChannelPipeline addFirst(ChannelHandler... handlers) {
return this.addFirst((EventExecutorGroup)null, (ChannelHandler[])handlers);
} public final ChannelPipeline addFirst(EventExecutorGroup executor, ChannelHandler... handlers) {
if (handlers == null) {
throw new NullPointerException("handlers");
} else if (handlers.length != 0 && handlers[0] != null) {
int size;
for(size = 1; size < handlers.length && handlers[size] != null; ++size) {
;
} for(int i = size - 1; i >= 0; --i) {
ChannelHandler h = handlers[i];
this.addFirst(executor, (String)null, h);
} return this;
} else {
return this;
}
} public final ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler) {
final AbstractChannelHandlerContext newCtx;
synchronized(this) {
checkMultiplicity(handler);
name = this.filterName(name, handler);
newCtx = this.newContext(group, name, handler);
this.addFirst0(newCtx);
if (!this.registered) {
newCtx.setAddPending();
this.callHandlerCallbackLater(newCtx, true);
return this;
} EventExecutor executor = newCtx.executor();
if (!executor.inEventLoop()) {
newCtx.setAddPending();
executor.execute(new Runnable() {
public void run() {
DefaultChannelPipeline.this.callHandlerAdded0(newCtx);
}
});
return this;
}
} this.callHandlerAdded0(newCtx);
return this;
}
前面几种都是间接调用的第四种没什么好说的,直接看第四种addFirst
首先调用checkMultiplicity,检查ChannelHandlerAdapter在不共享的情况下是否重复:
private static void checkMultiplicity(ChannelHandler handler) {
if (handler instanceof ChannelHandlerAdapter) {
ChannelHandlerAdapter h = (ChannelHandlerAdapter)handler;
if (!h.isSharable() && h.added) {
throw new ChannelPipelineException(h.getClass().getName() + " is not a @Sharable handler, so can't be added or removed multiple times.");
} h.added = true;
} }
isSharable方法:
public boolean isSharable() {
Class<?> clazz = this.getClass();
Map<Class<?>, Boolean> cache = InternalThreadLocalMap.get().handlerSharableCache();
Boolean sharable = (Boolean)cache.get(clazz);
if (sharable == null) {
sharable = clazz.isAnnotationPresent(Sharable.class);
cache.put(clazz, sharable);
} return sharable;
}
首先尝试从当前线程的InternalThreadLocalMap中获取handlerSharableCache,(InternalThreadLocalMap是在Netty中使用高效的FastThreadLocal替代JDK的ThreadLocal使用的 Netty中FastThreadLocal源码分析)
InternalThreadLocalMap的handlerSharableCache方法:
public Map<Class<?>, Boolean> handlerSharableCache() {
Map<Class<?>, Boolean> cache = this.handlerSharableCache;
if (cache == null) {
this.handlerSharableCache = (Map)(cache = new WeakHashMap(4));
} return (Map)cache;
}
当当前线程的InternalThreadLocalMap中没有handlerSharableCache时,直接创建一个大小为4的WeakHashMap弱引用Map;
根据clazz从map中get,若是没有,需要检测当前clazz是否有Sharable注解,添加了Sharable注解的ChannelHandlerAdapter可以在不同Channel*享使用一个单例,前提是确保线程安全;
之后会将该clazz以及是否实现Sharable注解的情况添加在cache缓存中;
其中ChannelHandler的added是用来标识是否添加过;
回到addFirst方法:
checkMultiplicity成功结束后,调用filterName方法,给当前要产生的AbstractChannelHandlerContext对象产生一个名称,
然后调用newContext方法,产生AbstractChannelHandlerContext对象:
private AbstractChannelHandlerContext newContext(EventExecutorGroup group, String name, ChannelHandler handler) {
return new DefaultChannelHandlerContext(this, this.childExecutor(group), name, handler);
}
这里实际上产生了一个DefaultChannelHandlerContext对象:
final class DefaultChannelHandlerContext extends AbstractChannelHandlerContext {
private final ChannelHandler handler; DefaultChannelHandlerContext(DefaultChannelPipeline pipeline, EventExecutor executor, String name, ChannelHandler handler) {
super(pipeline, executor, name, isInbound(handler), isOutbound(handler));
if (handler == null) {
throw new NullPointerException("handler");
} else {
this.handler = handler;
}
} public ChannelHandler handler() {
return this.handler;
} private static boolean isInbound(ChannelHandler handler) {
return handler instanceof ChannelInboundHandler;
} private static boolean isOutbound(ChannelHandler handler) {
return handler instanceof ChannelOutboundHandler;
}
}
可以看到DefaultChannelHandlerContext 仅仅是将AbstractChannelHandlerContext和ChannelHandler封装了
在产生了DefaultChannelHandlerContext 对象后,调用addFirst0方法:
private void addFirst0(AbstractChannelHandlerContext newCtx) {
AbstractChannelHandlerContext nextCtx = this.head.next;
newCtx.prev = this.head;
newCtx.next = nextCtx;
this.head.next = newCtx;
nextCtx.prev = newCtx;
}
这里就是一个简单的双向链表的操作,将newCtx节点插入到了head后面
然后判断registered成员的状态:
private boolean registered;
在初始化时是false
registered若是false,首先调用AbstractChannelHandlerContext的setAddPending方法:
final void setAddPending() {
boolean updated = HANDLER_STATE_UPDATER.compareAndSet(this, 0, 1); assert updated; }
和前面说过的setAddComplete方法同理,通过CAS操作,将handlerState状态设置为ADD_PENDING
接着调用callHandlerCallbackLater方法:
private void callHandlerCallbackLater(AbstractChannelHandlerContext ctx, boolean added) {
assert !this.registered; DefaultChannelPipeline.PendingHandlerCallback task = added ? new DefaultChannelPipeline.PendingHandlerAddedTask(ctx) : new DefaultChannelPipeline.PendingHandlerRemovedTask(ctx);
DefaultChannelPipeline.PendingHandlerCallback pending = this.pendingHandlerCallbackHead;
if (pending == null) {
this.pendingHandlerCallbackHead = (DefaultChannelPipeline.PendingHandlerCallback)task;
} else {
while(pending.next != null) {
pending = pending.next;
} pending.next = (DefaultChannelPipeline.PendingHandlerCallback)task;
} }
首先断言判断registered可能存在的多线程改变,然后根据added判断产生何种类型的PendingHandlerCallback
PendingHandlerCallback是用来处理ChannelHandler的两种回调,定义如下:
private abstract static class PendingHandlerCallback implements Runnable {
final AbstractChannelHandlerContext ctx;
DefaultChannelPipeline.PendingHandlerCallback next; PendingHandlerCallback(AbstractChannelHandlerContext ctx) {
this.ctx = ctx;
} abstract void execute();
}
PendingHandlerAddedTask定义如下:
private final class PendingHandlerAddedTask extends DefaultChannelPipeline.PendingHandlerCallback {
PendingHandlerAddedTask(AbstractChannelHandlerContext ctx) {
super(ctx);
} public void run() {
DefaultChannelPipeline.this.callHandlerAdded0(this.ctx);
} void execute() {
EventExecutor executor = this.ctx.executor();
if (executor.inEventLoop()) {
DefaultChannelPipeline.this.callHandlerAdded0(this.ctx);
} else {
try {
executor.execute(this);
} catch (RejectedExecutionException var3) {
if (DefaultChannelPipeline.logger.isWarnEnabled()) {
DefaultChannelPipeline.logger.warn("Can't invoke handlerAdded() as the EventExecutor {} rejected it, removing handler {}.", new Object[]{executor, this.ctx.name(), var3});
} DefaultChannelPipeline.remove0(this.ctx);
this.ctx.setRemoved();
}
} }
}
除去异常处理,无论是在execute方法还是在run方法中,主要核心是异步执行callHandlerAdded0方法:
private void callHandlerAdded0(AbstractChannelHandlerContext ctx) {
try {
ctx.setAddComplete();
ctx.handler().handlerAdded(ctx);
} catch (Throwable var10) {
boolean removed = false; try {
remove0(ctx); try {
ctx.handler().handlerRemoved(ctx);
} finally {
ctx.setRemoved();
} removed = true;
} catch (Throwable var9) {
if (logger.isWarnEnabled()) {
logger.warn("Failed to remove a handler: " + ctx.name(), var9);
}
} if (removed) {
this.fireExceptionCaught(new ChannelPipelineException(ctx.handler().getClass().getName() + ".handlerAdded() has thrown an exception; removed.", var10));
} else {
this.fireExceptionCaught(new ChannelPipelineException(ctx.handler().getClass().getName() + ".handlerAdded() has thrown an exception; also failed to remove.", var10));
}
} }
除去异常处理,主要核心就两行代码,首先通过setAddComplete方法,设置handlerState状态为ADD_COMPLETE,然后回调ChannelHandler的handlerAdded方法,这个handlerAdded方法就很熟悉了,在使用Netty处理业务逻辑时,会覆盖这个方法。
PendingHandlerRemovedTask定义如下:
private final class PendingHandlerRemovedTask extends DefaultChannelPipeline.PendingHandlerCallback {
PendingHandlerRemovedTask(AbstractChannelHandlerContext ctx) {
super(ctx);
} public void run() {
DefaultChannelPipeline.this.callHandlerRemoved0(this.ctx);
} void execute() {
EventExecutor executor = this.ctx.executor();
if (executor.inEventLoop()) {
DefaultChannelPipeline.this.callHandlerRemoved0(this.ctx);
} else {
try {
executor.execute(this);
} catch (RejectedExecutionException var3) {
if (DefaultChannelPipeline.logger.isWarnEnabled()) {
DefaultChannelPipeline.logger.warn("Can't invoke handlerRemoved() as the EventExecutor {} rejected it, removing handler {}.", new Object[]{executor, this.ctx.name(), var3});
} this.ctx.setRemoved();
}
} }
}
和PendingHandlerAddedTask一样,主要还是异步调用callHandlerRemoved0方法:
private void callHandlerRemoved0(AbstractChannelHandlerContext ctx) {
try {
try {
ctx.handler().handlerRemoved(ctx);
} finally {
ctx.setRemoved();
}
} catch (Throwable var6) {
this.fireExceptionCaught(new ChannelPipelineException(ctx.handler().getClass().getName() + ".handlerRemoved() has thrown an exception.", var6));
} }
首先直接回调ChannelHandler的handlerRemoved方法,然后通过setRemoved方法将handlerState状态设置为REMOVE_COMPLETE
回到callHandlerCallbackLater,其中成员pendingHandlerCallbackHead定义:
private DefaultChannelPipeline.PendingHandlerCallback pendingHandlerCallbackHead;
结合PendingHandlerCallback 可知,这个pendingHandlerCallbackHead是 DefaultChannelPipeline存储的一条PendingHandlerCallback单链表,用来处理ChannelHandler的handlerAdded和handlerRemoved的回调,在add的这些方法里调用callHandlerCallbackLater时,added参数都为true,所以add的ChannelHandler只向pendingHandlerCallbackHead添加了handlerAdded的回调。
回到addFirst方法,若是registered为true,先获取EventExecutor,判断是否处于轮询中,若不是,则需要开启轮询线程直接异步执行callHandlerAdded0方法,若处于轮询,由于ChannelPipeline的调用是发生在轮询时的,所以还是直接异步执行callHandlerAdded0方法。
addFirst方法到此结束,再来看addLast方法,同样有好几种重载:
public final ChannelPipeline addLast(ChannelHandler handler) {
return this.addLast((String)null, (ChannelHandler)handler);
} public final ChannelPipeline addLast(String name, ChannelHandler handler) {
return this.addLast((EventExecutorGroup)null, name, handler);
} public final ChannelPipeline addLast(ChannelHandler... handlers) {
return this.addLast((EventExecutorGroup)null, (ChannelHandler[])handlers);
} public final ChannelPipeline addLast(EventExecutorGroup executor, ChannelHandler... handlers) {
if (handlers == null) {
throw new NullPointerException("handlers");
} else {
ChannelHandler[] var3 = handlers;
int var4 = handlers.length; for(int var5 = 0; var5 < var4; ++var5) {
ChannelHandler h = var3[var5];
if (h == null) {
break;
} this.addLast(executor, (String)null, h);
} return this;
}
} public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
final AbstractChannelHandlerContext newCtx;
synchronized(this) {
checkMultiplicity(handler);
newCtx = this.newContext(group, this.filterName(name, handler), handler);
this.addLast0(newCtx);
if (!this.registered) {
newCtx.setAddPending();
this.callHandlerCallbackLater(newCtx, true);
return this;
} EventExecutor executor = newCtx.executor();
if (!executor.inEventLoop()) {
newCtx.setAddPending();
executor.execute(new Runnable() {
public void run() {
DefaultChannelPipeline.this.callHandlerAdded0(newCtx);
}
});
return this;
}
} this.callHandlerAdded0(newCtx);
return this;
}
还是间接调用最后一种:
对比addFirst来看,只有addLast0不一样:
private void addLast0(AbstractChannelHandlerContext newCtx) {
AbstractChannelHandlerContext prev = this.tail.prev;
newCtx.prev = prev;
newCtx.next = this.tail;
prev.next = newCtx;
this.tail.prev = newCtx;
}
还是非常简单的双向链表基本操作,只不过这次,是将AbstractChannelHandlerContext插入到了tail之前
还有两个,addBefore和addAfter方法,和上述方法类似,就不再累赘
接下来看看ChannelPipeline是如何完成请求的传递的:
invokeHandlerAddedIfNeeded方法:
final void invokeHandlerAddedIfNeeded() {
assert this.channel.eventLoop().inEventLoop(); if (this.firstRegistration) {
this.firstRegistration = false;
this.callHandlerAddedForAllHandlers();
} }
断言判断是否处于轮询线程(ChannelPipeline处理请求都是在轮询线程中,都需要异步处理)
其中firstRegistration成员在DefaultChannelPipeline初始化时为true:
private boolean firstRegistration = true;
此时设置为false,表示第一次调用,以后都不再调用后面的callHandlerAddedForAllHandlers:
private void callHandlerAddedForAllHandlers() {
DefaultChannelPipeline.PendingHandlerCallback pendingHandlerCallbackHead;
synchronized(this) {
assert !this.registered; this.registered = true;
pendingHandlerCallbackHead = this.pendingHandlerCallbackHead;
this.pendingHandlerCallbackHead = null;
} for(DefaultChannelPipeline.PendingHandlerCallback task = pendingHandlerCallbackHead; task != null; task = task.next) {
task.execute();
} }
刚才说过registered初始是false,在这里判断符合,之后就令其为true,然后获取处理ChannelHandler的回调链表pendingHandlerCallbackHead,并且将pendingHandlerCallbackHead置为null
然后遍历这个单链表,处理ChannelHandler的handlerAdded和handlerRemoved的回调
fireChannelRegistered方法,当Channel完成了向Selector的注册后,会由channel的Unsafe进行回调,异步处理:
public final ChannelPipeline fireChannelRegistered() {
AbstractChannelHandlerContext.invokeChannelRegistered(this.head);
return this;
}
实际上的处理由AbstractChannelHandlerContext的静态方法invokeChannelRegistered完成,这里传递的参数head就是DefaultChannelPipeline初始化时创建的HeadContext:
static void invokeChannelRegistered(final AbstractChannelHandlerContext next) {
EventExecutor executor = next.executor();
if (executor.inEventLoop()) {
next.invokeChannelRegistered();
} else {
executor.execute(new Runnable() {
public void run() {
next.invokeChannelRegistered();
}
});
} }
可以看到实际上是异步执行head对象的invokeChannelRegistered方法:
private void invokeChannelRegistered() {
if (this.invokeHandler()) {
try {
((ChannelInboundHandler)this.handler()).channelRegistered(this);
} catch (Throwable var2) {
this.notifyHandlerException(var2);
}
} else {
this.fireChannelRegistered();
} }
其中invokeHandler是用来判断当前的handlerState状态:
private boolean invokeHandler() {
int handlerState = this.handlerState;
return handlerState == 2 || !this.ordered && handlerState == 1;
}
若是当前handlerState状态为ADD_COMPLETE,或者不需要提供EventExecutor并且状态为ADD_PENDING时返回true,否则返回false
在成立的情况下,调用ChannelInboundHandler的channelRegistered方法,由于当前是head,所以由HeadContext实现了:
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
DefaultChannelPipeline.this.invokeHandlerAddedIfNeeded();
ctx.fireChannelRegistered();
}
首先调用invokeHandlerAddedIfNeeded,处理ChannelHandler的handlerAdded和handlerRemoved的回调
然后调用ctx的fireChannelRegistered方法:
public ChannelHandlerContext fireChannelRegistered() {
invokeChannelRegistered(this.findContextInbound());
return this;
}
findContextInbound方法,用来找出下一个ChannelInboundInvoker:
private AbstractChannelHandlerContext findContextInbound() {
AbstractChannelHandlerContext ctx = this; do {
ctx = ctx.next;
} while(!ctx.inbound); return ctx;
}
从当前节点向后遍历,inbound之前说过,该方法就是找到下一个ChannelInboundInvoker的类型的AbstractChannelHandlerContext,然后调用静态方法invokeChannelRegistered,重复上述操作,若是在ChannelInboundHandler中没有重写channelRegistered方法,会一直执直到完所有ChannelHandler的channelRegistered方法。
ChannelInboundHandlerAdapter中的默认channelRegistered方法:
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelRegistered();
}
比HeadContext中的实现还简单,直接调用fireChannelRegistered向后传递
fireChannelRead方法,是在Selector轮循到读事件就绪,会由channel的Unsafe进行回调,异步处理:
public final ChannelPipeline fireChannelRead(Object msg) {
AbstractChannelHandlerContext.invokeChannelRead(this.head, msg);
return this;
}
还是从head开始调用AbstractChannelHandlerContext的静态方法invokeChannelRead:
static void invokeChannelRead(final AbstractChannelHandlerContext next, Object msg) {
final Object m = next.pipeline.touch(ObjectUtil.checkNotNull(msg, "msg"), next);
EventExecutor executor = next.executor();
if (executor.inEventLoop()) {
next.invokeChannelRead(m);
} else {
executor.execute(new Runnable() {
public void run() {
next.invokeChannelRead(m);
}
});
} }
和上面一个逻辑异步调用AbstractChannelHandlerContext对象的invokeChannelRead方法:
private void invokeChannelRead(Object msg) {
if (this.invokeHandler()) {
try {
((ChannelInboundHandler)this.handler()).channelRead(this, msg);
} catch (Throwable var3) {
this.notifyHandlerException(var3);
}
} else {
this.fireChannelRead(msg);
} }
这里也和上面一样,调用了HeadContext的channelRead方法:
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.fireChannelRead(msg);
}
这里直接不处理,调用ChannelHandlerContext 的fireChannelRead方法:
public ChannelHandlerContext fireChannelRead(Object msg) {
invokeChannelRead(this.findContextInbound(), msg);
return this;
}
和之前注册一样,选择下一个ChannelInboundHandler,重复执行上述操作。
再来看到writeAndFlush方法,和上面的就不太一样,这个发生在轮询前,用户通过channel来间接调用,在AbstractChannel中实现:
public ChannelFuture writeAndFlush(Object msg) {
return this.pipeline.writeAndFlush(msg);
}
实际上直接调用了DefaultChannelPipeline的writeAndFlush方法:
public final ChannelFuture writeAndFlush(Object msg) {
return this.tail.writeAndFlush(msg);
}
这里又有些不一样了,调用了tail的writeAndFlush方法,即TailContext的writeAndFlush,在AbstractChannelHandlerContext中实现:
public ChannelFuture writeAndFlush(Object msg) {
return this.writeAndFlush(msg, this.newPromise());
}
newPromise产生了一个ChannelPromise,用来处理异步事件的;实际上调用了writeAndFlush的重载:
public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {
if (msg == null) {
throw new NullPointerException("msg");
} else if (this.isNotValidPromise(promise, true)) {
ReferenceCountUtil.release(msg);
return promise;
} else {
this.write(msg, true, promise);
return promise;
}
}
继续调用write方法:
private void write(Object msg, boolean flush, ChannelPromise promise) {
AbstractChannelHandlerContext next = this.findContextOutbound();
Object m = this.pipeline.touch(msg, next);
EventExecutor executor = next.executor();
if (executor.inEventLoop()) {
if (flush) {
next.invokeWriteAndFlush(m, promise);
} else {
next.invokeWrite(m, promise);
}
} else {
Object task;
if (flush) {
task = AbstractChannelHandlerContext.WriteAndFlushTask.newInstance(next, m, promise);
} else {
task = AbstractChannelHandlerContext.WriteTask.newInstance(next, m, promise);
} safeExecute(executor, (Runnable)task, promise, m);
} }
还是很相似,只不过先调用findContextOutbound找到下一个ChannelOutboundInvoker类型的ChannelHandlerContext,而且这里是从尾部往前遍历的,这样来看前面所给的图是没有任何问题的
在找到ChannelOutboundInvoker后,调用invokeWriteAndFlush或者invokeWrite方法:
invokeWriteAndFlush方法:
private void invokeWriteAndFlush(Object msg, ChannelPromise promise) {
if (this.invokeHandler()) {
this.invokeWrite0(msg, promise);
this.invokeFlush0();
} else {
this.writeAndFlush(msg, promise);
} } private void invokeWrite0(Object msg, ChannelPromise promise) {
try {
((ChannelOutboundHandler)this.handler()).write(this, msg, promise);
} catch (Throwable var4) {
notifyOutboundHandlerException(var4, promise);
} } private void invokeFlush0() {
try {
((ChannelOutboundHandler)this.handler()).flush(this);
} catch (Throwable var2) {
this.notifyHandlerException(var2);
} }
可以看到invokeWriteAndFlush回调了ChannelOutboundHandler的write和flush方法
最终会调用HeadContext的write和flush方法:
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
this.unsafe.write(msg, promise);
} public void flush(ChannelHandlerContext ctx) throws Exception {
this.unsafe.flush();
}
可以看到调用了unsafe的write和flush方法,向unsafe缓冲区写入了消息,当Selector轮询到写事件就绪时,就会通过unsafe将刚才写入的内容交由JDK的SocketChannel完成最终的write操作。
ChannelPipeline的分析到此全部结束。