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

相关推荐
智慧老师1 分钟前
Spring基础分析13-Spring Security框架
java·后端·spring
lxyzcm3 分钟前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
古希腊掌管学习的神29 分钟前
[LeetCode-Python版]相向双指针——611. 有效三角形的个数
开发语言·python·leetcode
赵钰老师30 分钟前
【R语言遥感技术】“R+遥感”的水环境综合评价方法
开发语言·数据分析·r语言
V+zmm1013435 分钟前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm
就爱学编程38 分钟前
重生之我在异世界学编程之C语言小项目:通讯录
c语言·开发语言·数据结构·算法
Oneforlove_twoforjob1 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
emoji1111111 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
xmh-sxh-13141 小时前
常用的缓存技术都有哪些
java
每天都要学信号1 小时前
Python(第一天)
开发语言·python