Netty源碼分析第7章(編碼器和寫數據)---->第2節: MessageToByteEncoder

 

Netty源碼分析第七章: Netty源碼分析html

 

第二節: MessageToByteEncoderpromise

 

同解碼器同樣, 編碼器中也有一個抽象類叫MessageToByteEncoder, 其中定義了編碼器的骨架方法, 具體編碼邏輯交給子類實現源碼分析

解碼器一樣也是個handler, 將寫出的數據進行截取處理, 咱們在學習pipeline中咱們知道, 寫數據的時候會傳遞write事件, 傳遞過程當中會調用handler的write方法, 因此編碼器碼器能夠重寫write方法, 將數據編碼成二進制字節流而後再繼續傳遞write事件學習

首先看MessageToByteEncoder的類聲明:編碼

public abstract class MessageToByteEncoder<I> extends ChannelOutboundHandlerAdapter{ //省略類體
}

這裏繼承ChannelOutboundHandlerAdapter, 說明是個outBoundhandler, 咱們知道write事件是個outBound事件, 而outBound事件只能經過outBoundHandler進行傳輸spa

write事件傳播過程當中要調用handler的write方法code

咱們跟到MessageToByteEncoder的write方法中:htm

public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { ByteBuf buf = null; try { if (acceptOutboundMessage(msg)) { @SuppressWarnings("unchecked") I cast = (I) msg; buf = allocateBuffer(ctx, cast, preferDirect); try { encode(ctx, cast, buf); } finally { ReferenceCountUtil.release(cast); } if (buf.isReadable()) { ctx.write(buf, promise); } else { buf.release(); ctx.write(Unpooled.EMPTY_BUFFER, promise); } buf = null; } else { ctx.write(msg, promise); } } catch (EncoderException e) { throw e; } catch (Throwable e) { throw new EncoderException(e); } finally { if (buf != null) { buf.release(); } } }

首先經過 if (acceptOutboundMessage(msg)) 判斷當前對象是否可處理對象

若是可處理, 則進入if塊中的邏輯, 若是不能處理, 則進入else塊, 經過ctx.write(msg, promise)繼續傳遞write事件blog

咱們看if塊中

 I cast = (I) msg 這裏是強制類型轉換, 轉換成I類型, I類型是個泛型, 具體類型由用戶定義

 buf = allocateBuffer(ctx, cast, preferDirect) 這裏進行緩衝區分配

跟到allocateBuffer方法中:

protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, @SuppressWarnings("unused") I msg, boolean preferDirect) throws Exception { if (preferDirect) { return ctx.alloc().ioBuffer(); } else { return ctx.alloc().heapBuffer(); } }

這裏會直接經過ctx的內存分配器進行內存分配, 經過判斷preferDirect來分配堆內存或者堆外內存, 默認狀況下是分配堆外內存

有關內存分配, 咱們以前已經作過相關的剖析

回到write方法中:

內存分配結束以後會調用encode(ctx, cast, buf)方法進行編碼, 該類由子類實現

子類能夠經過繼承該類, 重寫encode方法, 將參數對象cast編碼成字節寫入到傳入的ByteBuf中, 就完成了編碼工做

編碼完成後後, 會經過ReferenceCountUtil.release(cast)將cast對象釋放

 if (buf.isReadable()) 這裏判斷buf是否有可讀字節, 若是有可讀字節, 則繼續傳遞write事件

若是沒有可讀字節, 則將buf進行釋放, 繼續傳播write事件, 傳遞一個空的ByteBuf

最後將buf設置爲空

以上就是有關抽象編碼器的抽象邏輯, 具體的編碼邏輯還須要其子類去作

 

上一節: writeAndlush事件傳播

下一節: 寫buffer隊列

相關文章
相關標籤/搜索