本系列源码是基于netty 4.1.6版本。
netty服务端启动代码如下:
public final class Server {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childOption(ChannelOption.TCP_NODELAY, true)
.childAttr(AttributeKey.newInstance("childAttr"), "childAttrValue")
.handler(new ServerHandler())
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new AuthHandler());
//..
}
});
ChannelFuture f = b.bind(8000).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
进入b.bind(8000),最终进入AbstractBootstrap的doBind方法中
该方法第一行final ChannelFuture regFuture = initAndRegister()就是本节讲解的内容。进入该方法:
final ChannelFuture initAndRegister() {
Channel channel = null;
try {
channel = channelFactory.newChannel();
init(channel);
} catch (Throwable t) {
if (channel != null) {
// channel can be null if newChannel crashed (eg SocketException("too many open files"))
channel.unsafe().closeForcibly();
}
// as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor
return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
}
ChannelFuture regFuture = config().group().register(channel);
if (regFuture.cause() != null) {
if (channel.isRegistered()) {
channel.close();
} else {
channel.unsafe().closeForcibly();
}
}
return regFuture;
}
由上述代码可知channelFactory.newChannel()创建了一个channel。
这个channelFactory的类型是ReflectiveChannelFactory,并且里面的属性clazz的值是NioServerSocketChannel.class。由此我们可以推测出上述的赋值是通过b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)实现的。进入channel方法:
public B channel(Class<? extends C> channelClass) {
if (channelClass == null) {
throw new NullPointerException("channelClass");
}
return channelFactory(new ReflectiveChannelFactory<C>(channelClass));
}
这个方法的作用就是给channelFactory赋值以及给ReflectiveChannelFactory中的clazz赋值。
进入ReflectiveChannelFactory的newChannel方法:
@Override
public T newChannel() {
try {
return clazz.newInstance();
} catch (Throwable t) {
throw new ChannelException("Unable to create Channel from class " + clazz, t);
}
}
由此可知创建的channel是通过用户传入NioServerSocketChannel.class这个参数,然后通过反射机制构造出NioServerSocketChannel这个对象。
进入NioServerSocketChannel的构造函数:
public NioServerSocketChannel() {
this(newSocket(DEFAULT_SELECTOR_PROVIDER));
}
newSocket(DEFAULT_SELECTOR_PROVIDER)的作用是调用SelectorProvider.provider()..openServerSocketChannel()方法构造出java原生的serversocketchannel。进入下面方法:
public NioServerSocketChannel(ServerSocketChannel channel) {
super(null, channel, SelectionKey.OP_ACCEPT);
config = new NioServerSocketChannelConfig(this, javaChannel().socket());
}
该方法的作用是调用父类构造函数,并且生成一个配置类对象。
至此,完成了服务端channel创建