当前位置:首页 > 科技 > 正文

java高级面试题:客户端channel的初始化

1.3 客户端 Channel 的初始化

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

java高级面试题:客户端channel的初始化

在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);}

这里的代码比较关键,我们看到,在这个构造器中会调用 newSocket()来打开一个新的 Java NIO 的 SocketChannel:

private static SocketChannel newSocket(SelectorProvider provider) {// 删除了 try...catch块return provider.openSocketChannel();}

接着会调用父类, 即 AbstractNioByteChannel 的构造器:

AbstractNioByteChannel(Channel parent, SelectableChannel ch);

并传入参数 parent 为 null, ch 为刚才调用 newSocket()创建的 Java NIO 的 SocketChannel 对象, 因此新创建的NioSocketChannel 对象中 parent 暂时是 null。

protected AbstractNioByteChannel(Channel parent, SelectableChannel ch) {super(parent, ch, SelectionKey.OP_READ);}

接着会继续调用父类 AbstractNioChannel 的构造器,并传入实际参数 readInterestOp = SelectionKey.OP_READ:

protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {super(parent);this.ch = ch;this.readInterestOp = readInterestOp;// 省略...catch块// 设置 Java NIO SocketChannel为非阻塞的ch.configureBlocking(false);}

然后继续调用父类 AbstractChannel 的构造器:

protected AbstractChannel(Channel parent) {this.parent = parent;id = newId();unsafe = newUnsafe();pipeline = newChannelPipeline();}

至此, NioSocketChannel 就初始化就完成了, 我们可以稍微总结一下NioSocketChannel 初始化所做的工作内容:

1、调用NioSocketChannel.newSocket(DEFAULT_SELECTOR_PROVIDER)打开一个新的 Java NIOSocketChannel。

2、AbstractChannel(Channel parent)中需要初始化的属性:

id:每个 Channel 都拥有一个唯一的 id。

parent:属性值为 null。

unsafe:通过 newUnsafe()实例化一个 unsafe 对象,它的类型是 AbstractNioByteChannel.NioByteUnsafe 内部类。

pipeline:是 new DefaultChannelPipeline(this)新创建的实例。

3、AbstractNioChannel 中的属性:

ch:赋值为 Java SocketChannel,即 NioSocketChannel 的 newSocket()方法返回的 Java NIO SocketChannel。

readInterestOp:赋值为 SelectionKey.OP_READ

ch:被配置为非阻塞,即调用 ch.configureBlocking(false)。

4、NioSocketChannel 中的属性:

config = new NioSocketChannelConfig(this, socket.socket());


感谢阅读,喜欢的可以关注点赞,随意地交流分享。

本站文章部分来源于网友投稿或采集自互联网,如有侵权,请联系,本站将及时删除。 另也欢迎广大网友投稿发文!

相关文章:

  • golang2021数据格式(73)Go语言list(列表)
  • 发表评论

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。