Netty6 揭开BootStrap 的神秘面纱

6.1.1 Channel 简介
在Netty 中,Channel 是一个Socket 的抽象,它为用户提供了关于Socket 状态(是否是连接还是断开)以及对Socket
的读写等操作。每当Netty 建立了一个连接后, 都创建一个对应的Channel 实例。
除了TCP 协议以外,Netty 还支持很多其他的连接协议, 并且每种协议还有NIO(非阻塞IO)和OIO(Old-IO, 即传统的
阻塞IO)版本的区别。不同协议不同的阻塞类型的连接都有不同的Channel 类型与之对应下面是一些常用的Channel

Netty6 揭开BootStrap 的神秘面纱_第1张图片

6.1.2 NioSocketChannel 的创建

客户端的代码片段:

public class ChatClient {
   public ChatClient connect(int port,String host,final String nickName){
       EventLoopGroup group = new NioEventLoopGroup();//指定EventLoopGroup
       try {
                Bootstrap bootstrap = new Bootstrap();
                bootstrap.group(group)
               .channel(NioSocketChannel.class)
               .option(ChannelOption.SO_KEEPALIVE, true)
               .handler(new ChannelInitializer() {
   @Override
   protected void initChannel(SocketChannel ch) throws Exception {
      ...
                                }
       });
//发起同步连接操作
     ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
      channelFuture.channel().closeFuture().sync();
       }

   catch (InterruptedException e) {
       e.printStackTrace();
   }finally{
     //关闭,释放线程资源
    group.shutdownGracefully();
   }return this;
  }
   public static void main(String[] args) {
          new ChatClient().connect(8080, "localhost","Tom 老师");
}

从上面的客户端代码虽然简单, 但是却展示了Netty 客户端初始化时所需的所有内容:
1、EventLoopGroup:不论是服务器端还是客户端, 都必须指定EventLoopGroup。在这个例子中, 指定了
NioEventLoopGroup, 表示一个NIO 的EventLoopGroup。

2、ChannelType: 指定Channel 的类型。因为是客户端,因此使用了NioSocketChannel。
3、Handler: 设置处理数据的Handler。

NioSocketChannel 的类层次结构如下:

Netty6 揭开BootStrap 的神秘面纱_第2张图片

回到我们在客户端连接代码的初始化Bootstrap 中调用了一个channel()方法,传入的参数是NioSocketChannel.class,
在这个方法中其实就是初始化了一个ReflectiveChannelFactory 的对象:
public B channel(Class channelClass) {
    if (channelClass == null) {
     throw new NullPointerException("channelClass");
    }

   return channelFactory(new ReflectiveChannelFactory(channelClass));
}
而ReflectiveChannelFactory 实现了ChannelFactory 接口, 它提供了唯一的方法, 即newChannel()方法,
ChannelFactory, 顾名思义, 就是创建Channel 的工厂类。进入到ReflectiveChannelFactory 的newChannel()方法中。

根据上面代码的提示,我们就可以得出:
1、Bootstrap 中的ChannelFactory 实现类是ReflectiveChannelFactory。
2、通过channel()方法创建的Channel 具体类型是NioSocketChannel。

Channel 的实例化过程其实就是调用ChannelFactory 的newChannel()方法,而实例化的Channel 具体类型又是和初
始化Bootstrap 时传入的channel()方法的参数相关。因此对于客户端的Bootstrap 而言,创建的Channel 实例就是
NioSocketChannel。

6.1.3 客户端Channel 的初始化

前面我们已经知道了如何设置一个Channel 的类型,并且了解到Channel 是通过ChannelFactory 的newChannel()方
法来实例化的, 那么ChannelFactory 的newChannel()方法在哪里调用呢?继续跟踪, 我们发现其调用链如下:

Netty6 揭开BootStrap 的神秘面纱_第3张图片

在AbstractBootstrap 的initAndRegister()中调用了ChannelFactory()的newChannel()来创建一个NioSocketChannel
的实例,其源码如下:
final ChannelFuture initAndRegister() {
// 去掉非关键代码
Channel channel = channelFactory.newChannel();
init(channel);
ChannelFuture regFuture = config().group().register(channel);
// 去掉非关键代码
return regFuture;
}
在newChannel()方法中,利用反射机制调用类对象的newInstance()方法来创建一个新的Channel 实例,相当于调用
NioSocketChannel 的默认构造器。NioSocketChannel 的默认构造器代码如下:
public NioSocketChannel() {
this(DEFAULT_SELECTOR_PROVIDER);

你可能感兴趣的:(bootstrap,网络,前端)