1. initAndRegister-createChannel分析
2. initAndRegister-createChannel分析
3. ChannelInitializer分析
创建channel-server端bind()调用链如下

sever端启动主要处理都在bind()处理中,其中主要代码如下
AbstractBootstrap
private ChannelFuture doBind(final SocketAddress localAddress) {
final ChannelFuture regFuture = initAndRegister();
final Channel channel = regFuture.channel();
if (regFuture.cause() != null) {
return regFuture;
}
final ChannelPromise promise;
if (regFuture.isDone()) {
promise = channel.newPromise();
doBind0(regFuture, channel, localAddress, promise);
} else {
// Registration future is almost always fulfilled already, but just in case it's not.
promise = new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE);
regFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
doBind0(regFuture, channel, localAddress, promise);
}
});
}
return promise;
}
其中最重要的两个部分已经标出,先来分析一下initAndRegister()
分析initAndRegister方法
时序图如下

final ChannelFuture initAndRegister() {
Channel channel;
try {
//创建channel,并配置其主要属性
channel = createChannel();
} catch (Throwable t) {
return VoidChannel.INSTANCE.newFailedFuture(t);
}
try {
//初始化channel
init(channel);
} catch (Throwable t) {
channel.unsafe().closeForcibly();
return channel.newFailedFuture(t);
}
//创建ChannelPromise
ChannelPromise regFuture = channel.newPromise();
channel.unsafe().register(regFuture);
if (regFuture.cause() != null) {
if (channel.isRegistered()) {
channel.close();
} else {
channel.unsafe().closeForcibly();
}
}
return regFuture;
}
1.createChannel分析
ServerBootstrap:
Channel createChannel() {
EventLoop eventLoop = group().next();
return channelFactory().newChannel(eventLoop, childGroup);
}
ServerBootstrapChannelFactory
@Override
public T newChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
try {
//class=NioSocketChannel.class,调用它的构造方法。
Constructor extends T> constructor = clazz.getConstructor(EventLoop.class, EventLoopGroup.class);
return constructor.newInstance(eventLoop, childGroup);
} catch (Throwable t) {
throw new ChannelException("Unable to create Channel from class " + clazz, t);
}
}
//调用NioServerSocketChannel构造方法创建实例
public NioServerSocketChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
//调用父类构造方法
super(null, eventLoop, childGroup, newSocket(), SelectionKey.OP_ACCEPT);
//创建默认配置
config = new DefaultServerSocketChannelConfig(this, javaChannel().socket());
}
protected AbstractNioMessageServerChannel(
Channel parent, EventLoop eventLoop, EventLoopGroup childGroup, SelectableChannel ch, int readInterestOp) {
//调用父类构造方法
//此时parent=null 。ch=ServerSocketChannelImp(java原生的)
super(parent, eventLoop, ch, readInterestOp);
//childGroup赋值
this.childGroup = childGroup;
}
protected AbstractNioMessageChannel(
Channel parent, EventLoop eventLoop, SelectableChannel ch, int readInterestOp) {
//调用父类构造方法
super(parent, eventLoop, ch, readInterestOp);
}
protected AbstractNioChannel(Channel parent, EventLoop eventLoop, SelectableChannel ch, int readInterestOp) {
//调用父类构造方法
super(parent, eventLoop);
// 赋值 java SocketChannelImpl
this.ch = ch;
this.readInterestOp = readInterestOp;
try {
//配置java.nio.ServerSocketChannel为非阻塞
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);
}
}
最后调用
protected AbstractChannel(Channel parent, EventLoop eventLoop) {
this.parent = parent;
// 非空和兼容校验
this.eventLoop = validate(eventLoop);
unsafe = newUnsafe();//初始化unsafe××重要×××
pipeline = new DefaultChannelPipeline(this);//初始化pipeline××重要×××
}
AbstractNioChannel
//兼容校验
protected boolean isCompatible(EventLoop loop) {
return loop instanceof NioEventLoop;
}
小结:createChannel创建了 unsafe,pipeline,java.nio.ServerSocketChannel,然后为其属性eventLoop,childGroup,readInterestOp,config 赋值。
eventLoop是什么时候创建的 ?
创建 EventLoopGroup时创建的
2.init分析
void init(Channel channel) throws Exception {
final Map
//options value= {SO_BACKLOG=128}
synchronized (options) {
channel.config().setOptions(options);
}
final Map
//attrs={}
synchronized (attrs) {
for (Entry
@SuppressWarnings("unchecked")
AttributeKey