Netty源碼分析第1章(Netty啓動流程)---->第3節: 服務端channel初始化

 

Netty源碼分析第一章:Netty啓動流程html

 

第三節:服務端channel初始化ide

 

回顧上一小節的initAndRegister()方法:oop

final ChannelFuture initAndRegister() { Channel channel = null; try { //建立channel
        channel = channelFactory.newChannel(); //初始化channel
 init(channel); } catch (Throwable t) { //忽略非關鍵代碼
 } ChannelFuture regFuture = config().group().register(channel); //忽略非關鍵代碼
    return regFuture; }

簡單回顧上一小節內容, 咱們跟完了建立channel的步驟, 知道了Netty的NioServerSocketChannel和jdk的ServerSocketChannel之間的關係, NioServerSocketChannel和jdk的channel是組合關係, 在其父類AbstractChannel中有jdk的channel的一個成員變量, 經過建立netty的channel爲jdk的channel賦值源碼分析

 

咱們繼續往下看init(Channel)方法學習

由於是ServerBootstrap對象調用的init()方法, 因此咱們跟到ServerBootstrap類的init()方法中:spa

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; //選項轉化爲Entry對象(6)
    synchronized (childOptions) { currentChildOptions = childOptions.entrySet().toArray(newOptionArray(childOptions.size())); } //屬性轉化爲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)是獲取的用戶代碼中定義的選項和屬性netty

 

步驟(3)是獲取channel的pipeline, 這個channel就是上一小節咱們學習建立的NioServerSocketChannel, 咱們知道每一個channel都有個pipeline的屬性, 是AbstractChannel的成員變量, 而這裏的pipeline()就是獲取其與channel綁定的pipeline, 這個pipline, 會在後面的章節中講到code

 

步驟(4)是獲取worker線程組, 咱們知道這個worker線程組就是在用戶代碼中建立的NioEventLoopGroup, 後來在ServerBootstrap的group()方法中賦值爲ServerBootstrap的成員變量, 而這裏是獲取其成員變量, 並賦值到局部變量currentChildGroup中, NioEventLoop相關知識會在後面的章節講到htm

 

步驟(6), (7)是將選項和屬性轉化成Entry對象

 

步驟(8)是添加服務端Handler, 是經過和channel綁定的pipeline調用addLast()方法進行添加, 傳入一個ChannelInitializer類的子類對象, 至於addLast方法是作什麼的, ChannelInitializer是作什麼的, 後緒章節都會給你們詳細剖析, 這裏沒必要深究

 

這一小節咱們瞭解了有關channel初始化的過程, 咱們目前只需瞭解其大概步驟, 有關addLast的邏輯會在後面的章節進行詳細剖析

 
上一節: NioServerSocketChannel的建立

下一節: 註冊多路複用

相關文章
相關標籤/搜索