Netty啟動(dòng)流程服務(wù)端channel初始化源碼分析
前文傳送門(mén) Netty分布式server啟動(dòng)流程
服務(wù)端channel初始化
回顧上一小節(jié)initAndRegister()方法
final ChannelFuture initAndRegister() {
Channel channel = null;
try {
//創(chuàng)建channel
channel = channelFactory.newChannel();
//初始化channel
init(channel);
} catch (Throwable t) {
//忽略非關(guān)鍵代碼
}
ChannelFuture regFuture = config().group().register(channel);
//忽略非關(guān)鍵代碼
return regFuture;
}簡(jiǎn)單回顧上一小節(jié)內(nèi)容, 我們跟完了創(chuàng)建channel的步驟, 知道了Netty的NioServerSocketChannel和jdk的ServerSocketChannel之間的關(guān)系, NioServerSocketChannel和jdk的channel是組合關(guān)系, 在其父類(lèi)AbstractChannel中有jdk的channel的一個(gè)成員變量, 通過(guò)創(chuàng)建netty的channel為jdk的channel賦值
init(Channel)方法
我們繼續(xù)往下看init(Channel)方法
因?yàn)槭荢erverBootstrap對(duì)象調(diào)用的init()方法, 所以我們跟到ServerBootstrap類(lèi)的init()方法中:
void init(Channel channel) throws Exception {
//獲取用戶(hù)定義的選項(xiàng)(1)
final Map<ChannelOption<?>, Object> options = options0();
synchronized (options) {
channel.config().setOptions(options);
}
//獲取用戶(hù)定義的屬性(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線(xiàn)程組(4)
final EventLoopGroup currentChildGroup = childGroup;
//用戶(hù)設(shè)置的Handler(5)
final ChannelHandler currentChildHandler = childHandler;
final Entry<ChannelOption<?>, Object>[] currentChildOptions;
final Entry<AttributeKey<?>, Object>[] currentChildAttrs;
//選項(xiàng)轉(zhuǎn)化為Entry對(duì)象(6)
synchronized (childOptions) {
currentChildOptions = childOptions.entrySet().toArray(newOptionArray(childOptions.size()));
}
//屬性轉(zhuǎn)化為Entry對(duì)象(7)
synchronized (childAttrs) {
currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(childAttrs.size()));
}
//添加服務(wù)端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));
}
});
}
});
}初看起來(lái)代碼好長(zhǎng), 其實(shí)并不復(fù)雜, 這里對(duì)每一步進(jìn)行一個(gè)簡(jiǎn)述:
步驟(1), (2)是獲取的用戶(hù)代碼中定義的選項(xiàng)和屬性
步驟(3)是獲取channel的pipeline, 這個(gè)channel就是上一小節(jié)我們學(xué)習(xí)創(chuàng)建的NioServerSocketChannel, 我們知道每個(gè)channel都有個(gè)pipeline的屬性, 是AbstractChannel的成員變量, 而這里的pipeline()就是獲取其與channel綁定的pipeline, 這個(gè)pipline, 會(huì)在后面的章節(jié)中講到
步驟(4)是獲取worker線(xiàn)程組, 我們知道這個(gè)worker線(xiàn)程組就是在用戶(hù)代碼中創(chuàng)建的NioEventLoopGroup, 后來(lái)在ServerBootstrap的group()方法中賦值為ServerBootstrap的成員變量, 而這里是獲取其成員變量, 并賦值到局部變量currentChildGroup中, NioEventLoop相關(guān)知識(shí)會(huì)在后面的章節(jié)講到
步驟(6), (7)是將選項(xiàng)和屬性轉(zhuǎn)化成Entry對(duì)象
步驟(8)是添加服務(wù)端Handler, 是通過(guò)和channel綁定的pipeline調(diào)用addLast()方法進(jìn)行添加, 傳入一個(gè)ChannelInitializer類(lèi)的子類(lèi)對(duì)象, 至于addLast方法是做什么的, ChannelInitializer是做什么的, 后緒章節(jié)都會(huì)給大家詳細(xì)剖析, 這里不必深究
這一小節(jié)我們了解了有關(guān)channel初始化的過(guò)程, 我們目前只需了解其大概步驟, 有關(guān)addLast的邏輯會(huì)在后面的章節(jié)進(jìn)行詳細(xì)剖析
以上就是Netty啟動(dòng)流程服務(wù)端channel初始化源碼分析的詳細(xì)內(nèi)容,更多關(guān)于Netty啟動(dòng)流程服務(wù)端channel初始化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MybatisPlus?QueryWrapper常用方法實(shí)例
MyBatis-Plus(opens new window)是一個(gè)MyBatis(opens new window)的增強(qiáng)工具,在 MyBatis的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開(kāi)發(fā)、提高效率而生,下面這篇文章主要給大家介紹了關(guān)于MybatisPlus?QueryWrapper常用方法的相關(guān)資料,需要的朋友可以參考下2022-04-04
java中樂(lè)觀鎖與悲觀鎖區(qū)別及使用場(chǎng)景分析
本文主要介紹了java中樂(lè)觀鎖與悲觀鎖區(qū)別及使用場(chǎng)景分析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08
Java9中對(duì)集合類(lèi)擴(kuò)展的of方法解析
這篇文章主要介紹了Java9 中對(duì)集合類(lèi)擴(kuò)展的of方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
java發(fā)送http get請(qǐng)求的兩種方式
這篇文章主要為大家詳細(xì)介紹了java發(fā)送http get請(qǐng)求的兩種方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05
通過(guò)實(shí)例學(xué)習(xí)Spring @Required注釋原理
這篇文章主要介紹了通過(guò)實(shí)例學(xué)習(xí)Spring @Required注釋原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
Java多線(xiàn)程之ThreadLocal原理總結(jié)
這篇文章主要介紹了Java多線(xiàn)程ThreadLocal原理,同一個(gè)ThreadLocal所包含的對(duì)象,在不同的Thread中有不同的副本,文章中有詳細(xì)的代碼示例,需要的朋友參考一下2023-04-04
MyBatis之foreach標(biāo)簽的用法及多種循環(huán)問(wèn)題
這篇文章主要介紹了MyBatis之foreach標(biāo)簽的用法及多種循環(huán)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
Mybatis插入Oracle數(shù)據(jù)庫(kù)日期型數(shù)據(jù)過(guò)程解析
這篇文章主要介紹了Mybatis插入Oracle數(shù)據(jù)庫(kù)日期型數(shù)據(jù)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09

