NOTE
2.61 1.服务端的创建
bind 从这行代码开始,追踪bind 最终会来到io.netty.bootstrap.AbstractBootstrap#doBind - initAndRegister channel 要知道channelFactory是哪个,我们需要回到这行代码 - io.netty.bootstrap.Ab
这是历史学习笔记,可能存在过时或不完整的理解。
bind
从这行代码开始,追踪bind
ChannelFuture future = bootstrap.bind(8000).sync();
最终会来到io.netty.bootstrap.AbstractBootstrap#doBind
private ChannelFuture doBind(final SocketAddress localAddress) {
final ChannelFuture regFuture = initAndRegister();//这行
final Channel channel = regFuture.channel();
.....
}
- initAndRegister
final ChannelFuture initAndRegister() {
Channel channel = null;
//..
//调用channelFactory的newChannel创建,我们需要知道channelFactory是哪个?
channel = channelFactory.newChannel();
init(channel);
//...
return regFuture;
}
channel
要知道channelFactory是哪个,我们需要回到这行代码
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)//关键
- io.netty.bootstrap.AbstractBootstrap#channel
public B channel(Class<? extends C> channelClass) {
if (channelClass == null) {
throw new NullPointerException("channelClass");
}
//这个方法会将channelFactory赋值为ReflectiveChannelFactory
return channelFactory(new ReflectiveChannelFactory<C>(channelClass));
}
如上,我们知道了channelFactory.newChannel()中的factory是ReflectiveChannelFactory,并且服务器启动时对应的channelClass是NioServerSocketChannel.class。 首先看下他的newChannel方法
- io.netty.channel.ReflectiveChannelFactory#newChannel
public T newChannel() {
try {
//使用反射调用无参构造方法,即NioServerSocketChannel
return clazz.getConstructor().newInstance();
} catch (Throwable t) {
throw new ChannelException("Unable to create Channel from class " + clazz, t);
}
}
创建NioServerSocketChannel
- 构造方法
public NioServerSocketChannel() {
//newSocket是通过jdk底层的provider.openServerSocketChannel()
//接着调用有参构造方法
this(newSocket(DEFAULT_SELECTOR_PROVIDER));
}
public NioServerSocketChannel(ServerSocketChannel channel) {
//调用父类AbstractNioMessageChannel的构造
//AbstractNioMessageChannel会接着调用父类AbstractNioChannel的构造
super(null, channel, SelectionKey.OP_ACCEPT);
//参数配置类,用于配置options等
config = new NioServerSocketChannelConfig(this, javaChannel().socket());
}
- AbstractNioChannel
protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
//调用AbstractChannel
//客户端和服务器都是实现了他
super(parent);
this.ch = ch;
this.readInterestOp = readInterestOp;
try {
ch.configureBlocking(false);//nio配置为非阻塞模式
} 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);
}
}
-AbstractChannel
protected AbstractChannel(Channel parent) {
this.parent = parent;
id = newId();//channelId
unsafe = newUnsafe();//unsafe类,用于与底层jdk nio api交互
pipeline = newChannelPipeline();//创建pipeline
}