Netty的SimpleChannelInboundHandler分析

  • io.netty.channel.SimpleChannelInboundHandler是一个ChannelInboundHandler,它允许只处理一种明确的消息,这个消息的类型由泛型参数指定,例如String。
  • 这个类还有一个默认的特性,就是读过消息以后,可以将消息自动释放。如果读过消息以后不希望将消息继续传递给ChannelPipeline中后续的ChannelHandler,这个特性是有帮助的。
  • 当然,如果读过消息以后不希望自动释放,那么可以在创建SimpleChannelInboundHandler子类的实例的时候,调用SimpleChannelInboundHandler的构造函数SimpleChannelInboundHandler(boolean
    autoRelease),将构造函数中的参数autoRelease的值设置为false。如果不设置,默认为true。
  • SimpleChannelInboundHandler这个是一个抽象类,一个必须子类实现的函数是channelRead0(ChannelHandlerContext ctx, I msg)。但这个函数不是ChannelInboundHandler中的方法,而是SimpleChannelInboundHandler自己增加的方法。
  • channelRead0(ChannelHandlerContext ctx, I msg)这个方法会被channelRead(ChannelHandlerContext ctx, Object msg)方法调用。
  • 当Channel从对端读取到消息后,会调用channelRead(ChannelHandlerContext ctx, Object msg)方法,而channelRead(ChannelHandlerContext ctx, Object msg)方法会调用channelRead0(ChannelHandlerContext ctx, I msg)方法,所以SimpleChannelInboundHandler的子类实现channelRead0(ChannelHandlerContext ctx, I msg)方法即可。

我们看看SimpleChannelInboundHandler中channelRead(ChannelHandlerContext ctx, Object msg)方法的实现:

复制代码
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    boolean release = true;
    try {
        if (acceptInboundMessage(msg)) {
            @SuppressWarnings("unchecked")
            I imsg = (I) msg;
            channelRead0(ctx, imsg);
        } else {
            release = false;
            ctx.fireChannelRead(msg);
        }
    } finally {
        if (autoRelease && release) {
            ReferenceCountUtil.release(msg);
        }
    }
}
  • 上面源代码中,channelRead0(ctx, imsg)这条语句就是调用了被子类实现的channelRead0方法。

  • 下面再分析下if条件判断的逻辑:

    if (autoRelease && release) {

    ReferenceCountUtil.release(msg);

    }

这个if判断语句中,autoRelease就是构造函数传入的值,如果不传的话默认为true。当传入channelRead函数的消息类型跟泛型参数中的类型一致时,这个消息可以被处理,此时release的值为true。如果传入的消息跟泛型参数中指定的类型不同时,release的值被设置为false,这个消息不会被处理,只会简单地传递给ChannelPipeline中后续的ChannelHandler处理,这就是所谓的只明确处理一种消息的含义。

ReferenceCountUtil.release(msg)这个函数的作用就是将msg的引用计数减少1。如果引用计数减少到0,那么就将msg释放。当然,前提是msg实现了io.netty.util.ReferenceCounted接口。如果没有实现该接口,那么ReferenceCountUtil.release(msg)这条语句等于什么也没有做。

相关推荐
能摆一天是一天4 分钟前
JAVA stream().flatMap()
java·windows
CodeCraft Studio27 分钟前
PDF处理控件Aspose.PDF教程:使用 Python 将 PDF 转换为 Base64
开发语言·python·pdf·base64·aspose·aspose.pdf
零点零一29 分钟前
VS+QT的编程开发工作:关于QT VS tools的使用 qt的官方帮助
开发语言·qt
颜如玉1 小时前
🤲🏻🤲🏻🤲🏻临时重定向一定要能重定向🤲🏻🤲🏻🤲🏻
java·http·源码
程序员的世界你不懂2 小时前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
星空寻流年2 小时前
设计模式第一章(建造者模式)
java·设计模式·建造者模式
lingchen19063 小时前
MATLAB的数值计算(三)曲线拟合与插值
开发语言·matlab
gb42152873 小时前
java中将租户ID包装为JSQLParser的StringValue表达式对象,JSQLParser指的是?
java·开发语言·python
一朵梨花压海棠go3 小时前
html+js实现表格本地筛选
开发语言·javascript·html·ecmascript
曾经的三心草3 小时前
Python2-工具安装使用-anaconda-jupyter-PyCharm-Matplotlib
android·java·服务器