@Override@SuppressWarnings("Duplicates")publicfinal ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler){final AbstractChannelHandlerContext newCtx;//1.同步控制避免多线程并发操作pipeline底层的双向链表synchronized(this){//1.检查是否有重复handler,根据@Sharable判断是否允许重复添加checkMultiplicity(handler);//2.创建节点,Pipeline内部的节点是ChannelHandlerContext类型
newCtx =newContext(group,filterName(name, handler), handler);//3.添加节点addLast0(newCtx);//Channel还未注册,添加回调方法。注册完成后会执行回调方法。详细解析,见 {@link #invokeHandlerAddedIfNeeded} 方法。// If the registered is false it means that the channel was not registered on an eventloop yet.// In this case we add the context to the pipeline and add a task that will call// ChannelHandler.handlerAdded(...) once the channel is registered.if(!registered){//4.还未注册,则设置AbstractChannelHandlerContext准备添加中
newCtx.setAddPending();//5.此时Channel还没注册的EventLoop中,Netty中事件是在同一个EventLoop执行,所以//新增一个任务用于注册后添加 添加PendingHandlerCallback回调callHandlerCallbackLater(newCtx,true);returnthis;}
EventExecutor executor = newCtx.executor();//6.当前线程不在EventLoop的线程中,提交EventLoop中,执行回调用户方法if(!executor.inEventLoop()){//7.设置AbstractChannelHandlerContext准备添加中
newCtx.setAddPending();//8.提交EventLoop中,执行回调ChannelHandler added事件
executor.execute(newRunnable(){@Overridepublicvoidrun(){callHandlerAdded0(newCtx);}});returnthis;}}//9.回调ChannelHandler added 事件callHandlerAdded0(newCtx);returnthis;}
/**
* 检查ChannelHandler是否重复添加,如果ChannelHandler已经被重复添加则检查是否标注了@Sharable,
* 标注了那么就允许重复添加,反之没有标注则不允许再次添加
*
* 是否添加的标记是保存在ChannelHandler的一个added字段内部
* */privatestaticvoidcheckMultiplicity(ChannelHandler handler){if(handler instanceofChannelHandlerAdapter){
ChannelHandlerAdapter h =(ChannelHandlerAdapter) handler;//1.若已经添加且未使用@Sharable注解,则抛出异常if(!h.isSharable()&& h.added){thrownewChannelPipelineException(
h.getClass().getName()+" is not a @Sharable handler, so can't be added or removed multiple times.");}//2.标记已经添加,这个标记是在ChannelHandler中的,也就是说ChannelHandler自己可以记下自己是否//被某个ChannelPipline添加过,如果有@Sharable才允许被多次添加,反之则只能被添加一次
h.added =true;}}
/**
* 添加ChannelHandler到ChannelPipeline成功后出发回调
* */privatevoidcallHandlerAdded0(final AbstractChannelHandlerContext ctx){try{// We must call setAddComplete before calling handlerAdded. Otherwise if the handlerAdded method generates// any pipeline events ctx.handler() will miss them because the state will not allow it.//1.将AbstractChannelHandlerContext的添加状态设置为已添加
ctx.setAddComplete();//2.回调ChannelHandler的添加完成(added)事件(在添加完成之后,ChannelHandler还可以回调做点事情)
ctx.handler().handlerAdded(ctx);}catch(Throwable t){//3.如果发生异常,移除该节点boolean removed =false;try{//4.移除remove0(ctx);try{//5.回调ChannelHandler移除完成(removed)事件
ctx.handler().handlerRemoved(ctx);}finally{//6.标记节点已移除
ctx.setRemoved();}//7.标记移除成功
removed =true;}catch(Throwable t2){if(logger.isWarnEnabled()){
logger.warn("Failed to remove a handler: "+ ctx.name(), t2);}}//8.触发异常的传播if(removed){fireExceptionCaught(newChannelPipelineException(
ctx.handler().getClass().getName()+".handlerAdded() has thrown an exception; removed.", t));}else{fireExceptionCaught(newChannelPipelineException(
ctx.handler().getClass().getName()+".handlerAdded() has thrown an exception; also failed to remove.", t));}}}
privatevoidcallHandlerAddedForAllHandlers(){final PendingHandlerCallback pendingHandlerCallbackHead;//1.加锁、获得 pendingHandlerCallbackHeadsynchronized(this){assert!registered;// This Channel itself was registered.//2.标记已注册
registered =true;//3.链表头结点
pendingHandlerCallbackHead =this.pendingHandlerCallbackHead;// Null out so it can be GC'ed.// 置空,help gcthis.pendingHandlerCallbackHead = null;}//4.顺序遍历任务链表,执行全部PendingHandlerCallback回调任务// This must happen outside of the synchronized(...) block as otherwise handlerAdded(...) may be called while// holding the lock and so produce a deadlock if handlerAdded(...) will try to add another handler from outside// the EventLoop.
PendingHandlerCallback task = pendingHandlerCallbackHead;while(task != null){
task.execute();
task = task.next;}}