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
