东山明月

V1

2022/04/19阅读:26主题:蓝莹

2-1. 创建服务端channel

netty服务端channel中提到netty的初始化过程分为四步,本节详细记录其第一步创建服务端channel的过程。

1. 创建channel的总体过程

bind() -> initAndRegister() -> newChannel()

  1. 第一步在用户程序中调用调用bind()方法:
  1. 点进bind()方法,依次往下找可以看到第二步的initAndRegister()方法:
  1. 点进initAndRegister()方法之后可以看到第三步的newChannel()方法,通过channelFactory创建服务端的channel,其下一行的init(channel)是对channel的初始化过程,将在下一个小结进行详细分析。

那么现在的问题便是这里的newChannel()方法。

  1. newChannel()方法通过clazz.newInstance()的反射方法创建channel。那么这里的clazz到底是哪个类,根据源码一步一步找的过程如下:
  • 首先是标号1处ReflectiveChannelFactory类的构造方法,idea查看其被哪个类使用。至于为什么是ReflectiveChannelFactory类,首先是跟着闪电侠直接到了这个地方,之后在标号2处可以看到其正是new了一个这样的类。
  • 标号2处的channel方法中,new了一个ReflectiveChannelFactory类。而此处的channel方法则是在netty用户启动程序中被调用。
  • 标号3中调用channel方法,并传入NioServerSocketChannel.class类,而该类则一直被传到ReflectiveChannelFactory中,其clazz类正是由用户传入的NioServerSocketChannel.class,之后在调用反射方法创建channel。

小结:分析channel的创建过程,首先从用户程序的bind()方法进入,调用initAndRegister()方法初始化并且注册,之后再调用newChannel()方法创建出channel。创建channel的反射类是由用户从启动程序中传入的NioServerSocketChannel.class,至此channel创建的总体流程完成。接下来就需要看NioServerSocketChannel的构造函数中都做了哪些事情。

2. NioServerSocketChannel

闪电侠所给出NioServerSocketChannel构造方法的整体流程如下:

  1. 接上一小节,clazz.newInstance()调用NioServerSocketChannel类的无参构造方法创建channel对象,而NioServerSocketChannel提供了两个构造方法,其中无参构造使用默认的SelectorProvider,有参构造则需要提供一个SelectorProvider。

构造方法中调用newSocket(),通过SelectorProvider创建出一个ServerSocketChannel,这里的ServerSocketChannel便是jdk底层的channel。

  1. 两个构造方法均使用this关键字调用了NioServerSocketChannel的另一个构造器,并以此向上调用父类构造器,其过程如下图所示:

其中ch.configureBlocking(false)表示设置jdk底层的channel为非阻塞模式,这里的ch是从NioServerSocketChannel构造方法中传来的。AbstractChannel中设置了channel的id、unsafe、pipeline等属性。

  1. NioServerSocketChannel(ServerSocketChannel channel)调用父类构造方法之后有一个config,调用jdk底层代码设置TCP参数等细节内容。

分类:

后端

标签:

Java

作者介绍

东山明月
V1