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。