五Netty源码分析--3Bootstrap.bind--上
五Netty源码分析--3Bootstrap.bind--上
第三节 ServerBootstrap.bind()源码解析
3.1 ServerBootstrap配置方法
首先从ServerBootstrap的配置方法跟入,看如何实现
TAG0.1 parent属性设置
group传入,分别设置parentgroup和childgroup。
ServerBootstrap
public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
super.group(parentGroup);
ObjectUtil.checkNotNull(childGroup, "childGroup");
if (this.childGroup != null) {
throw new IllegalStateException("childGroup set already");
}
this.childGroup = childGroup;
return this;
}
AbstractBootstrap
public B group(EventLoopGroup group) {
ObjectUtil.checkNotNull(group, "group");
if (this.group != null) {
throw new IllegalStateException("group set already");
}
this.group = group;
return self();
}
跟入channel()方法,
AbstractBootstrap
public B channel(Class<? extends C> channelClass) {
//传入反射创建channel的工厂类ReflectiveChannelFactory
return channelFactory(new ReflectiveChannelFactory<C>(
ObjectUtil.checkNotNull(channelClass, "channelClass")
));
}
public B channelFactory(io.netty.channel.ChannelFactory<? extends C> channelFactory) {
return channelFactory((ChannelFactory<C>) channelFactory);
}
@Deprecated
public B channelFactory(ChannelFactory<? extends C> channelFactory) {
ObjectUtil.checkNotNull(channelFactory, "channelFactory");
if (this.channelFactory != null) {
throw new IllegalStateException("channelFactory set already");
}
//设置创建channel的反射工厂类
this.channelFactory = channelFactory;
return self();
}
根据channel传入的class类型,来反射创建channel实例的reflective工厂类
public class ReflectiveChannelFactory<T extends Channel> implements ChannelFactory<T> {
private final Class<? extends T> clazz;
public ReflectiveChannelFactory(Class<? extends T> clazz) {
if (clazz == null) {
throw new NullPointerException("clazz");
}
this.clazz = clazz;
}
@Override
public T newChannel() {
try {
//反射创建channel对应的实例
return clazz.newInstance();
} catch (Throwable t) {
throw new ChannelException("Unable to create Channel from class " + clazz, t);
}
}
然后,跟入设置ChannelHandler的方法:
AbstractBootstrap //父类中
//设置parent的handler
public B handler(ChannelHandler handler) {
this.handler = ObjectUtil.checkNotNull(handler, "handler");
return self();
}
TAG0.2 Child属性设置
ServerBootstrap
//设置server端启动类中的childHandler
public ServerBootstrap childHandler(ChannelHandler childHandler) {
this.childHandler = ObjectUtil.checkNotNull(childHandler, "childHandler");
return this;
}
区别:handler与childHandler
父类中的handler是客户端新接入的连接socketChannel对应的pipeline上的handler,因此是个工厂类,为每个新接入的客户端都创建一个新的handler。(该handler,用于在accept之前,父类给每个接入的channel,所加入的handler)
启动辅助类ServerBootstrap设置childhandler是NioServerSocketChannel对应的channelPipeline上的handler,所有连接该监听端口的客户端socketchannel都会执行该handler处理器;(该handler,用于accpet成功后,执行IO操作时,会链式处理的handler)
因此,两者的加入时机和处理阶段不同,如下图理解区别。
3.2 serverBootstrap.bind()方法
从如下位置跟入源码:
AbstractBootstrap
//bind作用:创建新的channel,并且绑定
public ChannelFuture bind(String inetHost, int inetPort) {
return bind(SocketUtils.socketAddress(inetHost, inetPort));
}
public ChannelFuture bind(SocketAddress localAddress) {
//验证group与channelFactory是否为null
validate();
return doBind(ObjectUtil.checkNotNull(localAddress, "localAddress"));
}
private ChannelFuture doBind(final SocketAddress localAddress) { //1
//TAG1 initAndRegister()
//创建并初始化serversocketchannel,将其注册到nioeventloop的selector,返回异步结果channelFuture
final ChannelFuture regFuture = initAndRegister();
//TAG2 ChannelFuture.channel
//从channelFuture获取新创建的channel
final Channel channel = regFuture.channel();
if (regFuture.cause() != null) {
return regFuture;
}
//异步操作有结果
if (regFuture.isDone()) { //2
// At this point we know that the registration was complete and successful.
ChannelPromise promise = channel.newPromise();
//TAG3 doBind0() 绑定指定的端口
doBind0(regFuture, channel, localAddress, promise);
return promise;
} else { //2
//TAG4 channelfuture异步机制
//异步操作尚未有结果(异步编程技巧)
final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel);
//针对异步操作没有结果的情况,可以为future.addlistener,实现该监听器操作完成时的方法定义,在异步操作完成后,继续进行后续的逻辑
regFuture.addListener(new ChannelFutureListener() { //3
@Override
//异步操作完成时,的listener逻辑
public void operationComplete(ChannelFuture future) throws Exception { //4
Throwable cause = future.cause();
if (cause != null) {
promise.setFailure(cause);
} else {
promise.executor = channel.eventLoop();
}
//监听channelfuture的异步操作结果完成后,继续原来逻辑操作doBind0
doBind0(regFuture, channel, localAddress, promise);
} //4
}); //3
return promise;
} //2
} //1
作图梳理doBind()的绑定操作逻辑:
dobind流程逻辑:
1 首先通过initAndRegister()方法,创建并初始化serverSocketChannel、注册到eventLoop的selector上,然后获取到channelFuture异步操作结果。
2 ChannelFuture.isDone()
2.1 如果异步操作有结果,根据操作获取channel,然后执行doBind0,bind该channel端口;
2.2 如果异步操作channelFuture没有结果,则通过添加listener监听,在异步操作完成时,doBind0,继续执行bind的逻辑操作。
这里针对异步操作future的编程技巧,[详见此处](# 4 future异步编程技巧(todo))
下面继续跟进bind的两大方法。
TAG1 initAndRegister()
AbstractBootstrap
final ChannelFuture initAndRegister() {
//TAG1.1 反射创建NioServerSocketChannel
final Channel channel = channelFactory().newChannel();
try {
//TAG1.2 初始化channel
init(channel);
} catch (Throwable t) {
if (channel != null) {
// channel can be null if newChannel crashed (eg SocketException("too many open files"))
channel.unsafe().closeForcibly();
return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
}
// as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor
return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
}
//TAG1.3 注册channel到selector
ChannelFuture regFuture = group().register(channel);
if (regFuture.cause() != null) {
if (channel.isRegistered()) {
channel.close();
} else {
channel.unsafe().closeForcibly();
}
}
// If we are here and the promise is not failed, it's one of the following cases:
// 1) If we attempted registration from the event loop, the registration has been completed at this point.
// i.e. It's safe to attempt bind() or connect() now because the channel has been registered.
// 2) If we attempted registration from the other thread, the registration request has been successfully
// added to the event loop's task queue for later execution.
// i.e. It's safe to attempt bind() or connect() now:
// because bind() or connect() will be executed *after* the scheduled registration task is executed
// because register(), bind(), and connect() are all bound to the same thread.
return regFuture;
}
该处代码,此处initAndRegister()主要做三部分操作:
//TAG1 反射创建NioServerSocketChannel
final Channel channel = channelFactory().newChannel();
//TAG2 初始化channel
init(channel);
//TAG3 注册channel到selector
ChannelFuture regFuture = group().register(channel);
TAG1.1 channelFactory().newChannel()--父channel创建
AbstractBootstrap
//返回channel工厂类
final ChannelFactory<? extends C> channelFactory() {
return channelFactory;
}
可知,当前工厂类,为serverbootstrap设置channel属性时,创建的reflectiveChannelFactory反射工厂。
然后,跟入newChannel()
ReflectiveChannelFactory
@Override
public T newChannel() {
try {
//根据clazz类,反射方法,调用无参构造函数创建NioServerSocketChannel
return clazz.newInstance();
} catch (Throwable t) {
throw new ChannelException("Unable to create Channel from class " + clazz, t);
}
}
在ServerBootstrap端传入的channel类为NioServerSocketChannel.class;此处clazz.newInstance(),调用channel类的无参构造。
public class NioServerSocketChannel extends AbstractNioMessageChannel
implements io.netty.channel.socket.ServerSocketChannel {
//TAG1.1.1 SelectorProvider.provider
//静态变量初始化,jvm中单例的provider实例,用来创建selector和原生channel
private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider();
public NioServerSocketChannel() {
//TAG1.1.2 newSocket(DEFAULT_SELECTOR_PROVIDER)
//TAG1.1.3 NioServerSocketChannel(ServerSocketChannel)
this(newSocket(DEFAULT_SELECTOR_PROVIDER));
}
private static ServerSocketChannel newSocket(SelectorProvider provider) {
try {
//使用provider创建NIO原生serverSocketChannel
return provider.openServerSocketChannel();
} catch (IOException e) {
throw new ChannelException(
"Failed to open a server socket.", e);
}
}
public NioServerSocketChannel(ServerSocketChannel channel) {
//TAG1.1.4 super(null, channel, SelectionKey.OP_ACCEPT)--Nettychannel注册
//第一个参数是父channel(server端channel,父channel为null)
//channel是NIO原生channel,accept是设置当前serversocketchannel关注事件为接受连接(server端为accept)
super(null, channel, SelectionKey.OP_ACCEPT);
config = new NioServerSocketChannelConfig(this, javaChannel().socket());
}
TAG1.1.1 SelectorProvider.provider
static final静态变量,会在构造函数执行前执行
SelectorProvider
public static SelectorProvider provider() {
synchronized (lock) {
if (provider != null)
return provider;
return AccessController.doPrivileged(
new PrivilegedAction<SelectorProvider>() {
public SelectorProvider run() {
if (loadProviderFromProperty())
return provider;
if (loadProviderAsService())
return provider;
provider = sun.nio.ch.DefaultSelectorProvider.create();
return provider;
}
});
}
}
这里SelectorProvider.provider()返回的是KQueueSelectorProvider对象。
TAG1.1.1.1 KQueueSelectorProvider
当前类是JDK的nio.ch下的类
package sun.nio.ch;
public class KQueueSelectorProvider extends SelectorProviderImpl {
public KQueueSelectorProvider() {
}
//获取selector选择器实例
public AbstractSelector openSelector() throws IOException {
return new KQueueSelectorImpl(this);
}
}
KQueueSelectorImpl
TAG1.1.2 newSocket(DEFAULT_SELECTOR_PROVIDER)
NioServerSocketChannel
private static ServerSocketChannel newSocket(SelectorProvider provider) {
try {
//TAG1.1.2.1 provider.openServerSocketChannel
//通过SelectorProvider创建ServerSocketChannel
return provider.openServerSocketChannel();
} catch (IOException e) {
throw new ChannelException(
"Failed to open a server socket.", e);
}
}
TAG1.1.2.1 provider.openServerSocketChannel--原生channel
public abstract class SelectorProviderImpl extends SelectorProvider {
public ServerSocketChannel openServerSocketChannel() throws IOException {
//创建NIO原生channel类
return new ServerSocketChannelImpl(this);
}
package sun.nio.ch; //JDK原生ServerSocketChannelImpl
class ServerSocketChannelImpl extends ServerSocketChannel implements SelChImpl {
ServerSocketChannelImpl(SelectorProvider var1) throws IOException {
super(var1);
this.fd = Net.serverSocket(true);
this.fdVal = IOUtil.fdVal(this.fd);
this.state = 0;
}
protected ServerSocketChannel(SelectorProvider provider) {
super(provider);
}
protected AbstractSelectableChannel(SelectorProvider provider) {
this.provider = provider;
}
当前provider为KQueueSelectorProvider
TAG1.1.3 NioServerSocketChannel(ServerSocketChannel)--原生Netty的channel
可知此处newSocket创建出的是原生ServerSocketChannel的实现类impl。
这里使用原生ServerSocketChannel创建Netty的NioServerSocketChannel。
NioServerSocketChannel
public NioServerSocketChannel(ServerSocketChannel channel) {
//TAG1.1.3.1
//第一个参数为parent channel,第二个参数channel为JDK原生serversocketchannel,第三个为当前channel所关注事件-ACCEPT
super(null, channel, SelectionKey.OP_ACCEPT);
//TAG1.1.3.2 NioServerSocketChannelConfig
config = new NioServerSocketChannelConfig(this, javaChannel().socket());
}
TAG1.1.3.1 AbstractNioChannel(Netty创建)
调用父类构造super时,设置关注事件为accept,此处是[位运算的编程技巧](#2 位运算(todo))
看到selectionKey中设置的事件的标志位,通过位运算设置的。
SelectionKey
public static final int OP_READ = 1 << 0; //read为1
public static final int OP_WRITE = 1 << 2; //write位4
public static final int OP_CONNECT = 1 << 3; //connect为8
public static final int OP_ACCEPT = 1 << 4; //accept为16
然后,跟入super父类
public abstract class AbstractNioMessageChannel extends AbstractNioChannel {
protected AbstractNioMessageChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
super(parent, ch, readInterestOp);
}
package io.netty.channel.nio; //netty的channel
public abstract class AbstractNioChannel extends AbstractChannel {
protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
//TAG1.1.3.1.1
//调用父类super构造函数
super(parent);
//该处ch为NIO原生channel
this.ch = ch;
//设置channel关注的事件类型
this.readInterestOp = readInterestOp;
try {
//设置当前channel非阻塞模式
ch.configureBlocking(false);
} catch (IOException e) {
try {
ch.close();
} catch (IOException e2) {
if (logger.isWarnEnabled()) {
logger.warn(
"Failed to close a partially initialized socket.", e2);
}
}
throw new ChannelException("Failed to enter non-blocking mode.", e);
}
}
该处构造函数中,完成如下任务:
调用父类super构造函数;将原生的NIO的serverSockerChannel设置NioServerSocketChannel;设置当前channel的关注事件readInterestOp为ACCPEPT;最后设置阻塞类型为非阻塞。
TAG1.1.3.1.1 AbstractChannel(创建channelpipeline)
继续跟入父类构造函数
protected AbstractChannel(Channel parent) {
this.parent = parent;
//设置channel唯一ID
id = DefaultChannelId.newInstance();
//在抽象channel中创建unsafe内部类
unsafe = newUnsafe();
//channel对应的pipeline在此处被创建(该pipeline与channel绑定)
pipeline = new DefaultChannelPipeline(this);
}
该处完成如下几个任务:
设置channel唯一ID,创建channel的底层操作类unsafe;创建与channel绑定的pipeline。
TAG1.1.3.2 NioServerSocketChannelConfig
public NioServerSocketChannel(ServerSocketChannel channel) {
super(null, channel, SelectionKey.OP_ACCEPT);
config = new NioServerSocketChannelConfig(this, javaChannel().socket());
}
此处,是netty的channel实例化过程中,创建config配置类,保存当前channel的属性。
1 javaChannel().socket()
NioServerSocketChannel
protected ServerSocketChannel javaChannel() {
return (ServerSocketChannel) super.javaChannel();
}
AbstractNioChannel
protected SelectableChannel javaChannel() {
return ch;
}
返回前面创建的Java原生ServerSocketChannelImpl对象。
class ServerSocketChannelImpl extends ServerSocketChannel implements SelChImpl {
//ServerSocketChannelImpl.socket()创建适配器类,把NIO原生ServerSocketChannelImpl的操作,交给adapter实现
public ServerSocket socket() {
synchronized(this.stateLock) {
if (this.socket == null) {
this.socket = ServerSocketAdaptor.create(this);
}
return this.socket;
}
}
2 NioServerSocketChannel.NioServerSocketChannelConfig(内部类)
config是NioServerSocketChannel的内部类
public DefaultServerSocketChannelConfig(ServerSocketChannel channel, ServerSocket javaSocket) {
super(channel);
if (javaSocket == null) {
throw new NullPointerException("javaSocket");
}
this.javaSocket = javaSocket;
}
TAG1.1.4 super(null, channel, SelectionKey.OP_ACCEPT)--Nettychannel初始化并注册
NioServerSocketChannel
public NioServerSocketChannel(ServerSocketChannel channel) {
//TAG1.1.4 super(null, channel, SelectionKey.OP_ACCEPT)--Nettychannel注册
//第一个参数是父channel(server端channel,父channel为null)
//channel是NIO原生channel,accept是设置当前serversocketchannel关注事件为接受连接(server端为accept)
super(null, channel, SelectionKey.OP_ACCEPT);
config = new NioServerSocketChannelConfig(this, javaChannel().socket());
}
在NioServerSocketChannel实例化时候,设置Netty的channel关注事件为OP_ACCEPT
public abstract class AbstractNioMessageChannel extends AbstractNioChannel {
boolean inputShutdown;
protected AbstractNioMessageChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
super(parent, ch, readInterestOp);
}
public abstract class AbstractNioChannel extends AbstractChannel {
private final SelectableChannel ch; //Netty的NioServerSocketChannel绑定的NIO原生serversocketchannel
protected final int readInterestOp; //设置NioServerSocketChannel关注的事件
volatile SelectionKey selectionKey;
boolean readPending;
protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
super(parent);
this.ch = ch;
this.readInterestOp = readInterestOp; //初始化时,设置NioServerSocketChannel关注事件为OP_ACCEPT
try {
ch.configureBlocking(false); //设置Netty为非阻塞
} catch (IOException e) {
try {
ch.close();
} catch (IOException e2) {
logger.warn(
"Failed to close a partially initialized socket.", e2);
}
throw new ChannelException("Failed to enter non-blocking mode.", e);
}
}
Netty的NioServerSocketChannel在初始化过程中,持有NIO原生channel,并设置server端channel关注的事件为OP_ACCEPT接受连接。
TAG1.2:init(channel)--初始化Netty的channel
AbstractBootstrap
//TAG1
final ChannelFuture initAndRegister() {
Channel channel = null;
try {
//TAG1.1
channel = channelFactory.newChannel();
//TAG1.2
init(channel);
}
然后回到initAndRegister()的主流程中,继续跟踪init(channel)。
ServerBootstrap
@Override
void init(Channel channel) {
/**………………………………………………………………………………设置serverbootstrap中parent属性到channel………………………………………………………………………………………… */
setChannelOptions(channel, options0().entrySet().toArray(newOptionArray(0)), logger);
setAttributes(channel, attrs0().entrySet().toArray(newAttrArray(0)));
//获取NioServerSocketChannel绑定的pipeline
ChannelPipeline p = channel.pipeline();
/**………………………………………………………………………………获取serverbootstrap中child属性option、attr………………………………………………………………………………………… */
//child相关属性,是连接入server后创建的NioSocketChannel对应的属性
final EventLoopGroup currentChildGroup = childGroup;
final ChannelHandler currentChildHandler = childHandler;
//获取serverbootstrap上的option、attr属性
final Entry<ChannelOption<?>, Object>[] currentChildOptions =
childOptions.entrySet().toArray(newOptionArray(0));
final Entry<AttributeKey<?>, Object>[] currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(0));
//TAG1.2.1 ChannelPipeline.addLast
//pipeline中添加自定义ChannelInitializer(该channelInitializer添加入pipeline,在完成channe初始化后,自动从pipeline中移除
p.addLast(new ChannelInitializer<Channel>() {
@Override
public void initChannel(final Channel ch) {
final ChannelPipeline pipeline = ch.pipeline();
ChannelHandler handler = config.handler();
if (handler != null) {
pipeline.addLast(handler);
}
ch.eventLoop().execute(new Runnable() {
@Override
public void run() {
//TAG1.2.2 ServerBootstrapAcceptor
//为ServerSocketChannel的pipeline中添加ServerBootstrapAcceptor处理器
//该处理器用来把childChannel的属性,添加入serversocketchannel.accpet生成的socketchannel的属性中
pipeline.addLast(new ServerBootstrapAcceptor(
ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
}
});
}
});
}
这里,init()主要完成属性的设置,分别为父属性和child属性的获取和设置。
父属性是serverbootstrap通过option、attr设置的,获取后设置入serversocketchannel中;
child属性,也是通过serverbootstrap通过childoption、childattr设置入,获取后,通过为serversocketchannel.pipeling添加ServerBootstrapAcceptor的ChannelInitializer处理器,其内为child的所有属性,负责为接入后的socketchannel设置child属性。
注意:
这里没有将serverbootstrap中handler加入pipeline中
着重分析如下流程:
//TAG1.2.1 ChannelPipeline.addLast
//pipeline中添加自定义ChannelInitializer(该channelInitializer添加入pipeline,在完成channe初始化后,自动从pipeline中移除
p.addLast(new ChannelInitializer<Channel>() {
@Override
public void initChannel(final Channel ch) {
final ChannelPipeline pipeline = ch.pipeline();
ChannelHandler handler = config.handler();
if (handler != null) {
pipeline.addLast(handler);
}
ch.eventLoop().execute(new Runnable() {
@Override
public void run() {
//TAG1.2.2 ServerBootstrapAcceptor
//为ServerSocketChannel的pipeline中添加ServerBootstrapAcceptor处理器
//该处理器用来把childChannel的属性,添加入serversocketchannel.accpet生成的socketchannel的属性中
pipeline.addLast(new ServerBootstrapAcceptor(
ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
}
});
}
});
}
TAG1.2.1 ChannelPipeline.addLast
DefaultChannelPipeline
@Override
public final ChannelPipeline addLast(ChannelHandler... handlers) {
return addLast(null, handlers);
}
@Override
public final ChannelPipeline addLast(EventExecutorGroup executor, ChannelHandler... handlers) {
if (handlers == null) {
throw new NullPointerException("handlers");
}
//遍历handlers,并包装为context加入pipeline中
for (ChannelHandler h: handlers) {
if (h == null) {
break;
}
addLast(executor, null, h);
}
return this;
}
@Override
public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
final AbstractChannelHandlerContext newCtx;
synchronized (this) { //1
checkMultiplicity(handler);
//由handler创建AbstractChannelHandlerContext
newCtx = newContext(group, filterName(name, handler), handler);
//加入pipeline中
addLast0(newCtx);
/**————————————————————————————————channelHandler.handlerAdded逻辑—————————————————————————————————————————————— */
//server端,启动时,第一次执行,执行这里
//register为false--表示channel尚未在eventloop上注册
if (!registered) {
//设置新创建的context状态为ADDPENDING
newCtx.setAddPending();
//TAG1.2.1.1 callHandlerCallbackLater
//将newCtx加入pipeline,并将newCtx加入HandlerCallbackLater的task任务中,一旦channel注册,就执行ChannelHandler.handlerAdded
callHandlerCallbackLater(newCtx, true);
return this;
}
EventExecutor executor = newCtx.executor();
//TAG1.2.1.2 callHandlerAddedInEventLoop
//在eventloop的线程中执行callHandlerAdded0---调用handleradd方法
if (!executor.inEventLoop()) {
callHandlerAddedInEventLoop(newCtx, executor);
return this;
}
} //1
//TAG1.2.1.3 callHandlerAdded0
//如果当前线程是eventloop,直接执行callHandlerAdded0
callHandlerAdded0(newCtx);
return this;
}
//加入pipeline尾,tail之前
private void addLast0(AbstractChannelHandlerContext newCtx) {
AbstractChannelHandlerContext prev = tail.prev;
newCtx.prev = prev;
newCtx.next = tail;
prev.next = newCtx;
tail.prev = newCtx;
}
这里加入了ChannelInitializer
ChannelPipeline.addLast(handler)逻辑:
pipeline中add(handler)逻辑:
synchronized (pipeline) {
1 handler--》创建对应的context对象,并将context加入pipeline的handlercontext的处理链中;
2 如果channel是否注册在nioeventloop上
2.1 如果没有注册:
将ctx设置为ADDPENDING状态,
//TAG1.2.1.1 callHandlerCallbackLater,将当前newCtx加入HandlerCallbackLater的task任务中,一旦channel注册,就执行ChannelHandler.handlerAdded
2.2 如果注册过
2.2.1 当前线程不是eventloop中线程
//TAG1.2.1.2 callHandlerAddedInEventLoop 在eventloop.executor.execute()中执行callHandlerAdded0--执行handler.add操作
}
3 如果当前线程是eventloop绑定的,那么操作pipeline是线程安全,不在synchronized (pipeline)中执行
直接//TAG1.2.1.3 callHandlerAdded0,执行handler.add操作
//TAG1.2.1.1 callHandlerCallbackLater(server端开启,只执行这里)
AbstractChannelHandlerContext
final void setAddPending() {
//设置context的状态为ADD_PENDING,代表当前context需要执行handler.add操作
boolean updated = HANDLER_STATE_UPDATER.compareAndSet(this, INIT, ADD_PENDING);
assert updated;
}
DefaultChannelPipeline
//added为true
private void callHandlerCallbackLater(AbstractChannelHandlerContext ctx, boolean added) {
assert !registered;
//将加入pipeline的handlercontext,创建并包装为PendingHandlerAddedTask--待执行handlerAdd操作的task
PendingHandlerCallback task = added ? new PendingHandlerAddedTask(ctx) : new PendingHandlerRemovedTask(ctx);
//获取需要执行handler.add操作任务的,列表的head(PendingHandlerCallback链的head)
PendingHandlerCallback pending = pendingHandlerCallbackHead;
if (pending == null) {
//如果head为null,直接将head设置为当前新创建的task
pendingHandlerCallbackHead = task;
} else {
// 找到pendingTask的尾部
while (pending.next != null) {
pending = pending.next;
}
//将新创建的task,加入PendingHandlerCallback链尾部
pending.next = task;
}
}
这里逻辑是,在channel尚未注册到nioeventloop时,将handler--》handlercontext加入pipeline后,将context包装成PendingHandlerAddedTask,并加入pipeline的task链尾部。当channel一旦注册到nioeventloop上,就执行pendingtask上的handler.add操作。
这里,task包裹ctx对应的channelhandler为:
//TAG1.2.1.2 callHandlerAddedInEventLoop(跳过)
DefaultChannelPipeline
private void callHandlerAddedInEventLoop(final AbstractChannelHandlerContext newCtx, EventExecutor executor) {
newCtx.setAddPending();
//在nioeventloop所在线程中,执行callHandlerAdded0---调用handler.added操作
executor.execute(new Runnable() {
@Override
public void run() {
//TAG1.2.1.3 callHandlerAdded0
callHandlerAdded0(newCtx);
}
});
}
//TAG1.2.1.3 callHandlerAdded0(跳过)
DefaultChannelPipeline
private void callHandlerAdded0(final AbstractChannelHandlerContext ctx) {
try {
//TAG1.2.1.3.1 handlerContext.callHandlerAdded
//调用handlercontext的handleradd操作
ctx.callHandlerAdded();
} catch (Throwable t) {
boolean removed = false;
try {
atomicRemoveFromHandlerList(ctx);
ctx.callHandlerRemoved();
removed = true;
} catch (Throwable t2) {
if (logger.isWarnEnabled()) {
logger.warn("Failed to remove a handler: " + ctx.name(), t2);
}
}
if (removed) {
fireExceptionCaught(new ChannelPipelineException(
ctx.handler().getClass().getName() +
".handlerAdded() has thrown an exception; removed.", t));
} else {
fireExceptionCaught(new ChannelPipelineException(
ctx.handler().getClass().getName() +
".handlerAdded() has thrown an exception; also failed to remove.", t));
}
}
}
//TAG1.2.1.3.1 handlerContext.callHandlerAdded(跳过)
AbstractChannelHandlerContext
final void callHandlerAdded() throws Exception {
//首先设置handlerContext的状态为ADD-COMPLETE
if (setAddComplete()) {
//HanAdd1 handler().handlerAdded(this)
handler().handlerAdded(this);
}
}
final boolean setAddComplete() {
for (;;) {
int oldState = handlerState;
if (oldState == REMOVE_COMPLETE) {
return false;
}
// 设置状态为ADD_COMPLETE
if (HANDLER_STATE_UPDATER.compareAndSet(this, oldState, ADD_COMPLETE)) {
return true;
}
}
}
//HanAdd1 handler().handlerAdded(this)(调用handler.handlerAdded)--channelInitializer的执行(跳过)
public interface ChannelHandler {
/**
* Gets called after the {@link ChannelHandler} was added to the actual context and it's ready to handle events.
*/
void handlerAdded(ChannelHandlerContext ctx) throws Exception;
当handler被真正添加入handlerContext后,会调用channelHandler.handlerAdded操作,之后,handler才能真正的准备好处理事件。
对于ChannelInitializer实现类来说:
ChannelInitializer
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
if (ctx.channel().isRegistered()) {
//HanADD1.1 ChannelInitializer.initChannel
//初始化channel---channelInitializer类的initChannel方法,会将childhandler添加入channelPipeline中
if (initChannel(ctx)) {
//HanAdd1.2 removeState---略
// We are done with init the Channel, removing the initializer now.
removeState(ctx);
}
}
}
//HanADD1.1 ChannelInitializer.initChannel(跳过)
ChannelInitializer
private boolean initChannel(ChannelHandlerContext ctx) throws Exception {
if (initMap.add(ctx)) { // Guard against re-entrance.
try {
//HanADD1.1.1 initChannel((C) ctx.channel())
initChannel((C) ctx.channel());
} catch (Throwable cause) {
// Explicitly call exceptionCaught(...) as we removed the handler before calling initChannel(...).
// We do so to prevent multiple calls to initChannel(...).
exceptionCaught(ctx, cause);
} finally {
ChannelPipeline pipeline = ctx.pipeline();
if (pipeline.context(this) != null) {
//HanAdd1.1.2 pipeline.remove(channelInitializer)
//将ChannelInitializer从pipeline中移除
pipeline.remove(this);
}
}
return true;
}
return false;
}
//HanADD1.1.1 initChannel((C) ctx.channel())--(跳过)
ctx.channel为handlerContext所绑定的channel。
这里,initChannel方法会执行ServerBootstrap中创建匿名类ServerBootstrap$1的initChannel方法。
该执行过程,会向pipeline中添加ServerBootstrapAcceptor类,其中currentChildHandler为Server启动程序中,添加的自定义channelInitializer类
//HanAdd1.1.2 pipeline.remove(channelInitializer)--略
DefaultChannelPipeline
@Override
public final ChannelPipeline remove(ChannelHandler handler) {
remove(getContextOrDie(handler));
return this;
}
public final ChannelPipeline remove(ChannelHandler handler) {
remove(getContextOrDie(handler));
return this;
}
private AbstractChannelHandlerContext remove(final AbstractChannelHandlerContext ctx) {
assert ctx != head && ctx != tail;
synchronized (this) {
atomicRemoveFromHandlerList(ctx);
// If the registered is false it means that the channel was not registered on an eventloop yet.
// In this case we remove the context from the pipeline and add a task that will call
// ChannelHandler.handlerRemoved(...) once the channel is registered.
if (!registered) {
callHandlerCallbackLater(ctx, false);
return ctx;
}
EventExecutor executor = ctx.executor();
if (!executor.inEventLoop()) {
executor.execute(new Runnable() {
@Override
public void run() {
callHandlerRemoved0(ctx);
}
});
return ctx;
}
}
callHandlerRemoved0(ctx);
return ctx;
}
这个逻辑,同TAG1.2.1 ChannelPipeline.addLast逻辑相同,省略