ChannelInboundHandlerAdapter和SimpleChannelInboundHandler是我們在使用Netty處理Handler時候很常用的兩個繼承類,雖然說二者實現的功能大致相同但是在一些細節上還是有很多不同的,本文主要來講一下兩者的不同。。。
ChannelInboundHandlerAdapter
ChannelInboundHandlerAdapter是ChannelInboundHandler一個簡單實現,默認情況下不會做任何處理。只是簡單的將操作通過fire*方法傳到ChannelPipeline中的下一個ChannelHandler中讓鏈中的下一個ChannelHandler去處理。。。
但是需要注意的是信息經過channelRead方法處理之后不會自動釋放(是因為信息不會被自動釋放所以能將信息傳給下一個ChannelHandler處理。)
SimpleChannelInboundHandler
SimpleChannelInboundHandler支持泛型的消息處理,默認情況下消息處理完之后將會自動釋放,無法提供fire*方法傳遞給ChannelPipeline中的下一個ChannelHandler,如果想要傳遞給下一個ChannelHandler需要調用ReferenceCountUtil#retain方法。
繼承使用此類的話需要實現 channelRead0方法:
protected abstract void channelRead0(ChannelHandlerContext ctx, I msg) throws Exception;
- 1
源碼注釋中說的是channelRead0方法在將來將會重命名為messageReceived:
但是在Netty的官方文檔中說的是Netty5版本已經被廢棄。
一般用netty來發送和接收數據都會繼承SimpleChannelInboundHandler和ChannelInboundHandlerAdapter這兩個抽象類,那么這兩個到底有什么區別呢?
其實用這兩個抽象類是有講究的,在客戶端的業務Handler繼承的是SimpleChannelInboundHandler,而在服務器端繼承的是ChannelInboundHandlerAdapter。
最主要的區別就是SimpleChannelInboundHandler在接收到數據后會自動release掉數據占用的Bytebuffer資源(自動調用Bytebuffer.release())。而為何服務器端不能用呢,因為我們想讓服務器把客戶端請求的數據發送回去,而服務器端有可能在channelRead方法返回前還沒有寫完數據,因此不能讓它自動release。