Netty學習之旅------原始碼分析Netty解碼編碼器實現原理
總結:package io.netty.handler.codec; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; import io.netty.util.ReferenceCountUtil; import io.netty.util.internal.TypeParameterMatcher; /** * {@link ChannelHandlerAdapter} which encodes message in a stream-like fashion from one message to an * {@link ByteBuf}. * * * Example implementation which encodes {@link Integer}s to a {@link ByteBuf}. * * <pre> * public class IntegerEncoder extends {@link MessageToByteEncoder}<{@link Integer}> { * {@code @Override} * public void encode({@link ChannelHandlerContext} ctx, {@link Integer} msg, {@link ByteBuf} out) * throws {@link Exception} { * out.writeInt(msg); * } * } * </pre> */ public abstract class MessageToByteEncoder<I> extends ChannelHandlerAdapter { private final TypeParameterMatcher matcher; private final boolean preferDirect; /** * @see {@link #MessageToByteEncoder(boolean)} with {@code true} as boolean parameter. */ protected MessageToByteEncoder() { this(true); } /** * @see {@link #MessageToByteEncoder(Class, boolean)} with {@code true} as boolean value. */ protected MessageToByteEncoder(Class<? extends I> outboundMessageType) { this(outboundMessageType, true); } /** * Create a new instance which will try to detect the types to match out of the type parameter of the class. * * @param preferDirect {@code true} if a direct {@link ByteBuf} should be tried to be used as target for * the encoded messages. If {@code false} is used it will allocate a heap * {@link ByteBuf}, which is backed by an byte array. */ protected MessageToByteEncoder(boolean preferDirect) { matcher = TypeParameterMatcher.find(this, MessageToByteEncoder.class, "I"); this.preferDirect = preferDirect; } /** * Create a new instance * * @param outboundMessageType The tpye of messages to match * @param preferDirect {@code true} if a direct {@link ByteBuf} should be tried to be used as target for * the encoded messages. If {@code false} is used it will allocate a heap * {@link ByteBuf}, which is backed by an byte array. */ protected MessageToByteEncoder(Class<? extends I> outboundMessageType, boolean preferDirect) { matcher = TypeParameterMatcher.get(outboundMessageType); this.preferDirect = preferDirect; } /** * Returns {@code true} if the given message should be handled. If {@code false} it will be passed to the next * {@link ChannelHandler} in the {@link ChannelPipeline}. */ public boolean acceptOutboundMessage(Object msg) throws Exception { return matcher.match(msg); } @Override 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(); } } } /** * Allocate a {@link ByteBuf} which will be used as argument of {@link #encode(ChannelHandlerContext, I, ByteBuf)}. * Sub-classes may override this method to returna {@link ByteBuf} with a perfect matching {@code initialCapacity}. */ protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, @SuppressWarnings("unused") I msg, boolean preferDirect) throws Exception { if (preferDirect) { return ctx.alloc().ioBuffer(); } else { return ctx.alloc().heapBuffer(); } } /** * Encode a message into a {@link ByteBuf}. This method will be called for each written message that can be handled * by this encoder. * * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToByteEncoder} belongs to * @param msg the message to encode * @param out the {@link ByteBuf} into which the encoded message will be written * @throws Exception is thrown if an error accour */ protected abstract void encode(ChannelHandlerContext ctx, I msg, ByteBuf out) throws Exception; }
相關推薦
Netty學習之旅------原始碼分析Netty解碼編碼器實現原理
package io.netty.handler.codec; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandler; import io.netty.c
Netty學習之旅------原始碼分析Netty執行緒本地分配機制與PooledByteBuf執行緒級物件池原理分析
final PoolArena<byte[]> heapArena; //使用輪叫輪詢機制,每個執行緒從heapArena[]中獲取一個,用於記憶體分配。 final PoolArena<ByteBuffer> directArena;
Netty學習之旅----原始碼分析Netty記憶體洩漏檢測
1、圖說Netty直接記憶體管理 2、Netty 直接記憶體的使用示例 ByteBuf buf = Unpooled.directBuffer(512); System.out.println(buf); // Si
Netty學習之旅----原始碼分析記憶體分配與釋放原理
static PooledHeapByteBuf newInstance(int maxCapacity) { PooledHeapByteBuf buf = RECYCLER.get(); buf.setRefCnt(1); buf.maxCapacity(m
Netty學習之旅----ThreadLocal原理分析與效能優化思考(思考篇)
/** * Returns the value in the current thread's copy of this * thread-local variable. If the variable has no value for the
Netty學習之旅----ByteBuf原始碼解讀之初探UnpooledHeapByteBuf、UnpooledDirectByteBuf
前沿: 在讀原始碼的過程中我發現有如下幾個點,感覺有問題: 1)UnpooledDirectByteBuf的 capacity(int newCapacity)方法,在readerIndex大於或等於newCapacity時,此時不需要將原ByteBuffer中的資
Netty學習篇⑥--ByteBuf原始碼分析
什麼是ByteBuf? ByteBuf在Netty中充當著非常重要的角色;它是在資料傳輸中負責裝載位元組資料的一個容器;其內部結構和陣列類似,初始化預設長度為256,預設最大長度為Integer.MAX_VALUE。 ByteBuf資料結構 * <pre> * +-----------
springMVC原始碼學習之addFlashAttribute原始碼分析
本文主要從falshMap初始化,存,取,消毀來進行原始碼分析,springmvc版本4.3.18。關於使用及驗證請參考另一篇https://www.cnblogs.com/pu20065226/p/10032048.html 1.初始化和呼叫,首先是入springMVC 入口webmvc包中org.spr
go 原始碼學習之---Tail 原始碼分析
已經有兩個月沒有寫部落格了,也有好幾個月沒有看go相關的內容了,由於工作原因最近在做java以及大資料相關的內容,導致最近工作較忙,部落格停止了更新,正好想撿起之前go的東西,所以找了一個原始碼學習 這個也是之前用go寫日誌收集的時候用到的一個包 :github.com/hpcloud/tail, 這次就學
SpringMVC原始碼學習之request處理流程 springMVC原始碼學習地址 springMVC原始碼學習之addFlashAttribute原始碼分析 java reflect反射呼叫方法invoke
目的:為看原始碼提供呼叫地圖,最長呼叫邏輯深度為8層,反正我是springMVC原始碼學習地址看了兩週才理出來的。 1.處理流程(版本為4.3.18) 入口為spring-webmvc-4.3.18.RELEASE.jar中org.springframework.web.servlet.Dispatche
Python學習之旅—Day07(生成器與叠代器)
討論 三次 iterable 結果 fis post 工作 映射 我們 前言 本篇博客主要專註於解決函數中的一個重要知識點——生成器與叠代器。不管是面試還是工作,生成器與叠代器在實際工作中的運用可以說是非常多,從我們第一天開始學習for循環來遍歷字典,列表等數據類
小程式學習之旅---表單元件 picker picker-view 實現日期 區域 聯動選擇
Page({ /** * 頁面的初始資料 */ data: { cityList: ['北京', '上海', '深圳', '廣州'], cityIndex: 1, time: '17:01', date: '2018-6-28',
WebService學習之旅(六)使用Apache Axis2實現WebService客戶端呼叫
上節介紹瞭如何使用Axis2 釋出一個WebService,Axis2除了為我們編寫WebService應用帶來了便利,也同樣簡化的客戶端呼叫的過程,本節在上節的基礎上使用Axis2自帶的工具生成客戶端呼叫輔助類,並實現客戶端呼叫程式碼的編寫。 1.將前面下載
Flask原始碼分析二:路由內部實現原理
前言 Flask是目前為止我最喜歡的一個Python Web框架了,為了更好的掌握其內部實現機制,這兩天準備學習下Flask的原始碼,將由淺入深跟大家分享下,其中Flask版本為1.1.1。 上次瞭解了Flask服務的啟動流程,今天我們來看下路由的內部實現機理。 Flask系列文章: Flask開發初探 F
原始碼分析 Alibaba sentinel 滑動視窗實現原理(文末附原理圖)
要實現限流、熔斷等功能,首先要解決的問題是如何實時採集服務(資源)呼叫資訊。例如將某一個介面設定的限流闊值 1W/tps,那首先如何判斷當前的 TPS 是多少?Alibaba Sentinel 採用滑動視窗來實現實時資料的統計。 > 溫馨提示:如果對原始碼不太感興趣,可以先跳到文末,看一下滑動視窗的設
Netty之旅三:Netty服務端啟動原始碼分析,一梭子帶走!
# Netty服務端啟動流程原始碼分析 ![](//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d5be8808ccb54c318b5abd21f97bd37f~tplv-k3u1fbpfcp-zoom-1.image) ## 前記 哈嘍,自從上篇《Netty之旅
【Netty之旅四】你一定看得懂的Netty客戶端啟動原始碼分析!
## 前言 前面小飛已經講解了`NIO`和`Netty`服務端啟動,這一講是`Client`的啟動過程。 原始碼系列的文章依舊還是遵循大白話+畫圖的風格來講解,本文`Netty`原始碼及以後的文章版本都基於:**4.1.22.Final** 本篇是以`NettyClient`啟動為切入點,帶大家一步步進
Netty學習之路(六)-分隔符和定長解碼器的應用
之前已經使用了LineBasedFrameDecoder解決TCP粘包問題,現在再學兩種解決TCP粘包的方法。 DelimiterBasedFrameDecoder:可以自動完成以分隔符做結束標誌的訊息的解碼,分隔符自定義。 FixedLengthFrameDecoder:
Netty學習之路(九)-JBoss Marshalling編解碼
JBoss Marshalling 是一個Java物件序列化包,對JDK預設的序列化框架進行了優化,但又保持跟java.io.Serializable介面的相容,同時增加了一些可調的引數和附加的特性。 Marshalling開發環境準備 下載相關的Marshalling類庫:地址,將
Netty學習之路(七)-編解碼技術
當進行遠端跨程序服務呼叫時,需要把被傳輸的Java物件編碼為位元組陣列或者ByteBuffer物件。而當遠端服務讀取到ByteBuffer物件或者位元組陣列時,需要將其解碼為傳送時的Java物件。這被稱為Java物件編解碼技術。而我們常見得Java序列化僅僅是Java編解碼技術的一種,由於j