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();……}……}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 原神冒险家试炼第五天怎么过
- 广州怎么去五台山
- 医疗垃圾桶分类五大类
- 五月初五端午节的来历和风俗
- 五年级期待落空的句子
- 剑南春和五粮液哪个好喝_剑南春和五粮液的口感区别
- 骰子五个点怎么玩(骰子五个六五个七怎么玩)
- 五线谱中小音符怎么弹
- 【前端必会】走进webpack生命周期,另类的学习方法
- opencvcv.line