Netty啟動流程服務端channel初始化源碼分析
前文傳送門 Netty分布式server啟動流程
服務端channel初始化
回顧上一小節(jié)initAndRegister()方法
final ChannelFuture initAndRegister() { Channel channel = null; try { //創(chuàng)建channel channel = channelFactory.newChannel(); //初始化channel init(channel); } catch (Throwable t) { //忽略非關鍵代碼 } ChannelFuture regFuture = config().group().register(channel); //忽略非關鍵代碼 return regFuture; }
簡單回顧上一小節(jié)內(nèi)容, 我們跟完了創(chuàng)建channel的步驟, 知道了Netty的NioServerSocketChannel和jdk的ServerSocketChannel之間的關系, NioServerSocketChannel和jdk的channel是組合關系, 在其父類AbstractChannel中有jdk的channel的一個成員變量, 通過創(chuàng)建netty的channel為jdk的channel賦值
init(Channel)方法
我們繼續(xù)往下看init(Channel)方法
因為是ServerBootstrap對象調(diào)用的init()方法, 所以我們跟到ServerBootstrap類的init()方法中:
void init(Channel channel) throws Exception { //獲取用戶定義的選項(1) final Map<ChannelOption<?>, Object> options = options0(); synchronized (options) { channel.config().setOptions(options); } //獲取用戶定義的屬性(2) final Map<AttributeKey<?>, Object> attrs = attrs0(); synchronized (attrs) { for (Entry<AttributeKey<?>, Object> e: attrs.entrySet()) { @SuppressWarnings("unchecked") AttributeKey<Object> key = (AttributeKey<Object>) e.getKey(); channel.attr(key).set(e.getValue()); } } //獲取channel的pipline(3) ChannelPipeline p = channel.pipeline(); //work線程組(4) final EventLoopGroup currentChildGroup = childGroup; //用戶設置的Handler(5) final ChannelHandler currentChildHandler = childHandler; final Entry<ChannelOption<?>, Object>[] currentChildOptions; final Entry<AttributeKey<?>, Object>[] currentChildAttrs; //選項轉(zhuǎn)化為Entry對象(6) synchronized (childOptions) { currentChildOptions = childOptions.entrySet().toArray(newOptionArray(childOptions.size())); } //屬性轉(zhuǎn)化為Entry對象(7) synchronized (childAttrs) { currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(childAttrs.size())); } //添加服務端handler(8) p.addLast(new ChannelInitializer<Channel>() { //初始化channel @Override public void initChannel(Channel ch) throws Exception { final ChannelPipeline pipeline = ch.pipeline(); ChannelHandler handler = config.handler(); if (handler != null) { pipeline.addLast(handler); } ch.eventLoop().execute(new Runnable() { @Override public void run() { pipeline.addLast(new ServerBootstrapAcceptor( currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs)); } }); } }); }
初看起來代碼好長, 其實并不復雜, 這里對每一步進行一個簡述:
步驟(1), (2)是獲取的用戶代碼中定義的選項和屬性
步驟(3)是獲取channel的pipeline, 這個channel就是上一小節(jié)我們學習創(chuàng)建的NioServerSocketChannel, 我們知道每個channel都有個pipeline的屬性, 是AbstractChannel的成員變量, 而這里的pipeline()就是獲取其與channel綁定的pipeline, 這個pipline, 會在后面的章節(jié)中講到
步驟(4)是獲取worker線程組, 我們知道這個worker線程組就是在用戶代碼中創(chuàng)建的NioEventLoopGroup, 后來在ServerBootstrap的group()方法中賦值為ServerBootstrap的成員變量, 而這里是獲取其成員變量, 并賦值到局部變量currentChildGroup中, NioEventLoop相關知識會在后面的章節(jié)講到
步驟(6), (7)是將選項和屬性轉(zhuǎn)化成Entry對象
步驟(8)是添加服務端Handler, 是通過和channel綁定的pipeline調(diào)用addLast()方法進行添加, 傳入一個ChannelInitializer類的子類對象, 至于addLast方法是做什么的, ChannelInitializer是做什么的, 后緒章節(jié)都會給大家詳細剖析, 這里不必深究
這一小節(jié)我們了解了有關channel初始化的過程, 我們目前只需了解其大概步驟, 有關addLast的邏輯會在后面的章節(jié)進行詳細剖析
以上就是Netty啟動流程服務端channel初始化源碼分析的詳細內(nèi)容,更多關于Netty啟動流程服務端channel初始化的資料請關注腳本之家其它相關文章!
相關文章
Spring+Vue整合UEditor富文本實現(xiàn)圖片附件上傳的方法
這篇文章主要介紹了Spring+Vue整合UEditor富文本實現(xiàn)圖片附件上傳的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-07-07IntelliJ IDEA像Eclipse一樣打開多個項目的圖文教程
這篇文章主要介紹了IntelliJ IDEA像Eclipse一樣打開多個項目的方法圖文教程講解,需要的朋友可以參考下2018-03-03Java的作業(yè)調(diào)度類庫Quartz基本使用指南
這篇文章主要介紹了Java的作業(yè)調(diào)度類庫Quartz基本使用指南,Quartz能夠讓類按照指定的計劃順序執(zhí)行,需要的朋友可以參考下2016-03-03Java中遍歷ConcurrentHashMap的四種方式詳解
這篇文章主要介紹了Java中遍歷ConcurrentHashMap的四種方式詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-10-10