Netty学习——源码篇2 客户端Bootstrap(一) 备份

 1 Channel简介

        在Netty中,Channel相当于一个Socket的抽象,它为用户提供了关于Socket状态(是连接还是断开)以及对Socket的读写等操作。每当Netty建立了一个连接,都创建一个与其对应的Channel实例。

        除了TCP,Netty还支持很多其他的协议,并且每种协议还有NIO和OIO(传统的阻塞IO)版本的区别。不同协议不同阻塞类型的连接都有不同的Channel类型与之对应,下表对一些常用的Channel做了简单介绍。

 

        来看一下Channel的总体类图,如下图:

 

2 NioSocketChannel的创建

        Bootstrap是Netty提供的一个便利的工厂类,可以通过它来完成客户端或者服务端的Netty的初始化。

        首先,从客户端开始分析。 

public class ChatClient {
    public ChatClient connect(int port,String host,final String name){
        NioEventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.SO_KEEPALIVE,true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            System.out.println("初始化channel:" + socketChannel);
                        }
                    });
            //发起同步连接操作
            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,"127.0.0.1","jay");
    }
}

         分析如下:

        1、EventLoopGroup:不论是服务端还是客户端,都必须指定EventLoopGroup。在本例中,指定了NioEventLoopGroup,表示一个NIO的EventLoopGroup。

        2、ChannelType:指定Channel的类型。因为是客户端,所以使用了NioSocketChannel。

        3、Handler:设置处理数据的Handler。

        客户端启动Bootstrap后都做了哪些工作?看一下NioSocketChannel的类层次结构图,如下:

        回到在客户端连接代码的初始化Bootstrap中,该方法调用了一个channel方法,传入的参数是NioSocketChannel.class,在这个方法中其实就是初始化了一个ReflectiveChannelFactory的对象,代码实现如下:

public B channel(Class<? extends C> channelClass) {
        if (channelClass == null) {
            throw new NullPointerException("channelClass");
        } else {
            return this.channelFactory((io.netty.channel.ChannelFactory)(new ReflectiveChannelFactory(channelClass)));
        }
    }

         而ReflectiveChannelFactory实现了ChannelFactory接口,它提供了唯一的方法,即newChannel方法。顾名思义,ChannelFactory就是创建Channel的工厂类。进入ReflectiveChannelFactory的newChannel方法,其实现代码如下:

public T newChannel() {
        try {
            return (Channel)this.clazz.newInstance();
        } catch (Throwable var2) {
            throw new ChannelException("Unable to create Channel from class " + this.clazz, var2);
        }
    }

        根据上面的代码,可以得出以下结论。

        1、Bootstrap中的ChannelFactory实现类是ReflectiveChannelFactory。

        2、通过channel方法创建的Channel具体类型是NioSocketChannel。

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

3 客户端Channel初始化

        上面提到了如何设置一个Channel的类型,并且了解到Channel是通过ChannelFactory的newChannel方法来实例化的,那么ChannelFactory的newChannel方法在哪里调用呢?其调用链路如下图:

        在AbstractBootstrap的initAndRegister方法中,调用ChannelFactory的newChannel方法来创建一个NioSocketChannel的实例,代码如下:

final ChannelFuture initAndRegister() {
        Channel channel = null;

        try {
            channel = this.channelFactory.newChannel();
            this.init(channel);
        } catch (Throwable var3) {
            if (channel !&#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

geminigoth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值