netty源码解析(一)服务端channel创建及初始化
本系列源码是基于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创建