免费A级毛片无码专区网站-成人国产精品视频一区二区-啊 日出水了 用力乖乖在线-国产黑色丝袜在线观看下-天天操美女夜夜操美女-日韩网站在线观看中文字幕-AV高清hd片XXX国产-亚洲av中文字字幕乱码综合-搬开女人下面使劲插视频

五 Netty 學習:服務端啟動核心流程源碼說明

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>服務端在啟動的時候,主要流程有如下幾個

  1. 創(chuàng)建服務端的 Channel
  2. 初始化服務端的 Channel
  3. 注冊 Selector
  4. 端口綁定
我們可以寫一個簡單的服務端代碼,通過 Debug 的方式查看這幾個關鍵流程的核心代碼 。
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事件,執(zhí)行任務 。EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try {// 服務端的一個啟動輔助類 。通過給它設置一系列參數(shù)來綁定端口啟動服務 。ServerBootstrap b = new ServerBootstrap();b// 設置服務端的線程模型 。// bossGroup 負責不斷接收新的連接,將新的連接交給 workerGroup 來處理 。.group(bossGroup, workerGroup)// 設置服務端的 IO 類型是 NIO 。Netty 通過指定 Channel 的類型來指定 IO 類型 。.channel(NioServerSocketChannel.class)// 服務端啟動過程中,需要經(jīng)過哪些流程 。.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 來處理每個連接的數(shù)據(jù).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中,調(diào)用的最關鍵的方法是如下兩個:
……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 進去,發(fā)現(xiàn)channelFactory.newChannel()實際上是調(diào)用了ReflectiveChannelFactorynewChannel方法,
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();……}……}

經(jīng)驗總結擴展閱讀