pipeline有一个主要的实现类 DefaultChannelPipeline ,addLast顾名思义,就是在处理器链的最后添加一个channelHandler。
代码如下:@Override public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
final AbstractChannelHandlerContext newCtx; synchronized (this) { checkMultiplicity(handler); ------------用channelHandlerContext包装这个handler newCtx = newContext(group, filterName(name, handler), handler); ------------这个方法其实没啥,简单的添加到后头 addLast0(newCtx); // 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) {---------------把ChannelHandlerContext中的handlerState这个volatile属性,从INIT状态设置成ADD_PENDING,意思是表明这个handler的状态从初始变成等待添加 newCtx.setAddPending(); callHandlerCallbackLater(newCtx, true); return this; } EventExecutor executor = newCtx.executor(); if (!executor.inEventLoop()) { newCtx.setAddPending();--------------将任务添加到NioEventLoop的队列中,等待执行,异步? executor.execute(new Runnable() { @Override public void run() {--------------这个方法,其实有两个逻辑:第一,处理handler被添加到处理器链的时候,要做的准备工作,因为只有做完了这些准备工作,才能处理数据。第二,把HandlerContext的handlerState设置成ADD_COMPLETE,不过,异步完成,会不会逻辑有问题?或者在channel开始处理数据之前,会检查判断?在注册之后会有一个invokeHandlerAddedIfNeeded,执行所有放入队列的相关任务。--------------handlerAdded这个名字的意思并不是添加handler,添加handler这个步骤在addlast0里做过了,而是让handler做被添加之后的准备工作--------------handlerContext的fire/invoke channelRegistered/active/inactive/unregister/read 都是handlerContext对channel时间的相应,比如channel被生成,初始化了,他所属的handler要被add,然后执行handleradded方法,为channel的处理做准备,接下来,channel被registered了,又要用context执行channelRegistered方法,这些逻辑其实有的都是重复的,都是为了channel的工作做准备。 callHandlerAdded0(newCtx); } }); return this; } } callHandlerAdded0(newCtx); return this; }