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)这条语句等于什么也没有做。

相关推荐
咸鱼2.0几秒前
【java入门到放弃】网络
java·开发语言·网络
阿里嘎多学长3 分钟前
2025-12-28 GitHub 热点项目精选
开发语言·程序员·github·代码托管
Roye_ack3 分钟前
【微服务 Day2】SpringCloud实战开发(微服务拆分步骤 + Nacos注册中心 + OpenFeign + 微服务拆分作业)
java·spring cloud·微服务·nacos·openfeign
wniuniu_5 分钟前
blob是啥
java·服务器·网络
.生产的驴11 分钟前
DockerCompoe 部署注册中心Nacos 一键部署 单机+Mysql8
java·linux·运维·spring boot·缓存·docker·doc
zmzb010312 分钟前
C++课后习题训练记录Day58
开发语言·c++
会员果汁16 分钟前
算法-并查集-C
c语言·开发语言·算法
hgz071019 分钟前
MyBatis插件(拦截器)
java·tomcat
熊猫钓鱼>_>26 分钟前
基于Trae/Whisper/FFmpeg与Knowledge Graph MCP技术开发语音生成会议纪要智能应用
开发语言·人工智能·python·深度学习·ffmpeg·whisper·trae
七夜zippoe33 分钟前
Python迭代器与生成器深度解析:从原理到协程应用实战
开发语言·python