Netty 学习(五):服务端启动核心流程源码说明作者: Grey
原文地址:
博客园:Netty 学习(五):服务端启动核心流程源码说明
CSDN:Netty 学习(五):服务端启动核心流程源码说明
说明本文使用的 Netty 版本是 4.1.82.Final,
<dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.82.Final</version></dependency>
服务端在启动的时候,主要流程有如下几个
- 创建服务端的 Channel
- 初始化服务端的 Channel
- 注册 Selector
- 端口绑定
package source;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;import io.netty.channel.ChannelInitializer;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioServerSocketChannel;/** * 代码阅读 * * @author <a href="mailto:410486047@qq.com">Grey</a> * @date 2022/9/12 * @since */public final class SimpleServer {public static void main(String[] args) throws InterruptedException {// EventLoopGroup: 服务端的线程模型外观类 。这个线程要做的事情// 就是不停地检测IO事件,处理IO事件,执行任务 。EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try {// 服务端的一个启动辅助类 。通过给它设置一系列参数来绑定端口启动服务 。ServerBootstrap b = new ServerBootstrap();b// 设置服务端的线程模型 。// bossGroup 负责不断接收新的连接 , 将新的连接交给 workerGroup 来处理 。.group(bossGroup, workerGroup)// 设置服务端的 IO 类型是 NIO 。Netty 通过指定 Channel 的类型来指定 IO 类型 。.channel(NioServerSocketChannel.class)// 服务端启动过程中,需要经过哪些流程 。.handler(new ChannelInboundHandlerAdapter() {@Overridepublic void channelActive(ChannelHandlerContext ctx) {System.out.println("channelActive");}@Overridepublic void channelRegistered(ChannelHandlerContext ctx) {System.out.println("channelRegistered");}@Overridepublic void handlerAdded(ChannelHandlerContext ctx) {System.out.println("handlerAdded");}})// 用于设置一系列 Handler 来处理每个连接的数据.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel socketChannel) {}});// 绑定端口同步等待 。等服务端启动完毕 , 才会进入下一行代码ChannelFuture f = b.bind(8888).sync();// 等待服务端关闭端口绑定 , 这里的作用是让程序不会退出f.channel().closeFuture().sync();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}}
通过ChannelFuture f = b.bind(8888).sync();
的bind
方法 , 进入源码进行查看 。首先 , 进入的是
AbstractBootstrap
中 , 调用的最关键的方法是如下两个:……private ChannelFuture doBind(final SocketAddress localAddress) {……final ChannelFuture regFuture = initAndRegister();……doBind0(regFuture, channel, localAddress, promise);……}……
进入initAndResgister()
方法中……final ChannelFuture initAndRegister() {……// channel 的新建channel = channelFactory.newChannel();// channel 的初始化init(channel);……}……
这里完成了 Channel 的新建和初始化 , Debug 进去,发现channelFactory.newChannel()
实际上是调用了ReflectiveChannelFactory
的newChannel
方法,public class ReflectiveChannelFactory<T extends Channel> implements ChannelFactory<T> {……private final Constructor<? extends T> constructor;public ReflectiveChannelFactory(Class<? extends T> clazz) {……this.constructor = clazz.getConstructor();……}@Overridepublic T newChannel() {……return constructor.newInstance();……}……}
这里调用了反射方法,其实就是将服务端代码中的这一行.channel(NioServerSocketChannel.class)
中的NioServerSocketChannel.class
传入进行对象创建,创建一个NioServerSocketChannel
实例 。在创建
NioServerSocketChannel
的时候,调用了NioServerSocketChannel
的构造方法,构造方法的主要逻辑如下……public NioServerSocketChannel(SelectorProvider provider, InternetProtocolFamily family) {this(newChannel(provider, family));}public NioServerSocketChannel(ServerSocketChannel channel) {super(null, channel, SelectionKey.OP_ACCEPT);config = new NioServerSocketChannelConfig(this, javaChannel().socket());}private static ServerSocketChannel newChannel(SelectorProvider provider, InternetProtocolFamily family) {……ServerSocketChannel channel =SelectorProviderUtil.newChannel(OPEN_SERVER_SOCKET_CHANNEL_WITH_FAMILY, provider, family);return channel == null ? provider.openServerSocketChannel() : channel;……}……
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 原神冒险家试炼第五天怎么过
- 剑南春和五粮液哪个好喝_剑南春和五粮液的口感区别
- 【前端必会】走进webpack生命周期,另类的学习方法
- opencvcv.line
- 骰子五个点怎么玩(骰子五个六五个七怎么玩)
- 三十六 Java开发学习----SpringBoot三种配置文件解析
- 4 MySQL学习---MySQL索引
- 五大珍贵树木 中国名贵树排名
- 基础&进阶 线段树学习笔记(一) | P3372 【模板】线段树 1 题解
- 苹果截屏的五种方法(iphone快速截图方法)