相信你們看了decoder部分的時候確定有點怪異,尤爲是發現重寫的方法是channelRead0。方法上還帶了數字,徹底不如channelRead好理解,下面的內容就是解答這個疑惑的。數組
第一個程序繼承的是ChannelInboundHandlerAdapter類,第二個程序是繼承的是SimpleChannelInboundHandler,SimpleChannelInboundHandler是有泛型參數的。能夠指定一個具體的類型參數,經過decoder配合使用,很是方便。ChannelInboundHandlerAdapter則是直接操做byte數組的。異步
ChannelInboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelInboundHandler
SimpleChannelInboundHandler<I> extends ChannelInboundHandlerAdapter
上圖就是兩個類的聲明,SimpleChannelInboundHandler是繼承ChannelInboundHandlerAdapter的。也就是說SimpleChannelInboundHandler也擁有ChannelInboundHandlerAdapter的方法。jvm
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { boolean release = true; try { if (acceptInboundMessage(msg)) {//類型匹配 I imsg = (I) msg; channelRead0(ctx, imsg); } else { release = false; ctx.fireChannelRead(msg); } } finally { if (autoRelease && release) { ReferenceCountUtil.release(msg);//釋放引用 } } }
SimpleChannelInboundHandler的channelRead相比SimpleChannelInboundHandler而言,主要作了類型匹配以及用完以後釋放指向保存該消息的 ByteBuf 的內存引用。學習
相比之下,ChannelInboundHandlerAdapter 好像一無可取,畢竟他要本身處理資源的釋放,例如以下的調用.net
buf.release();
若是說channelRead都是同步操做的話,SimpleChannelInboundHandler是不錯的選擇,若是操做是異步的話,那他的邏輯就有點麻煩了,例如你把數據交給另外的線程處理了,還沒處理就會釋放了 。這裏必須說明一個問題,他的回收和jvm的垃圾回收還不徹底是一回事。netty是本身作了引用計數的操做。線程
buf.refCnt();
經過上面的api就能夠獲取到計數的個數。具體的引用計數的部分,不知道也不影響netty的學習,這個點後面具體再說。ChannelInboundHandlerAdapter 處理自由的優勢也就提現出來了,能夠更好的處理更多的特定場景。netty
SimpleChannelInboundHandler的好處是能夠處理不一樣的類型對象,而且能夠作釋放。ChannelInboundHandlerAdapter 的好處則是更自由,在異步的場景下更適合。code