Netty之ChannelPipeline(六)

本文深入探讨Netty的ChannelPipeline机制,解析其内部结构及工作原理,包括DefaultChannelPipeline和DefaultChannelHandlerContext的角色,以及如何动态修改ChannelPipeline。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Pipeline是什么

在之前的Netty编程中我们可以看到需要添加一个解码器或者是一个处理器或者是一个粘包拆包处理器,都需要在一个pipeline中添加进去,那么这个pipeline到底是个什么东西?
在这里插入图片描述

ChannelPipeline

点进pipeline()方法发现是一个ChannelPipeline对象
在这里插入图片描述
首先
ChannelPipeline本质上其实是一个Map<String, DefaultChannelHandlerContext>存储DefaultChannelHandlerContext(我们传进去的每一个handler都会被构造成一个DefaultChannelHandlerContext对象)的map集合。
然后
我们找到ChannelPipeline的默认实现类DefaultChannelPipeline,首先我们找到我们使用的addLast方法,下面是addLast的调用栈:
可以看到我们调用方法的时候只传了一个ChannelPipeline,所以invoker默认是null,接下来在第二个儿addLast方法中,会循环遍历handlers(也就是我们穿进来的ChannelPipeline数组),然后依次调用第三个addLast,其中generateName(h)是下图中的最后一个方法,就是根据类名自动生成一个name,默认name#0,如果重复就加1,然后我们就来到了addLast方法,由于 Channelpipeline支持运行期动态修改,因此存在两种潜在的多线程并发访问场景,IO线程和用户业务线程的并发访问、用户多个线程之间的并发访问,所以对HashMap进行操作这里是加了锁的,然后检查刚刚生成的name是否重复(检查就是看那个HashMap里面是否包含这个Channelpipeline如果包含就抛出IllegalArgumentException Duplicate handler name: 异常),接着,用我们传入的ChannelPipeline构造出DefaultChannelHandlerContext,然后就来到了addLast0方法中,这里可以看到是经典的链表插入操作,然后就看到了this.name2ctx.put(name, newCtx)将ChannelPipeline添加到我们的map中,最后this.callHandlerAdded(newCtx)发送新增 Channelhandlercontext通知消息。
在这里插入图片描述
接下来
我们分析一下DefaultChannelPipeline和DefaultChannelHandlerContext的结构,
DefaultChannelPipeline

  • 看到一个WeakHashMap,这个是用来存储name缓存的,也就是每个被添加进来的ChannelPipeline在生成name的时候都要在这个里面判断是否已经有了,如果有了就将编号加一。
  • head,指向name2ctx集合中的头,
  • tail,执行name2ctx集合中的尾,
  • name2ctx存放注册进来的pipeline构造成的DefaultChannelHandlerContext,
  • childInvokers,存放的invoker的IdentityHashMap,IdentityHashMap是一种key可以重复的map
  • invoker是什么:就是负责绑定、连接、读写等操作的一个东西。
    在这里插入图片描述
    DefaultChannelHandlerContext
    找到构造方法:
    可以看到构造的时候把传入的handler赋给当前对象的handler了,
    注意看this.invoker = this.channel.unsafe().invoker(),invoker其实是调用Unsafe类的一个东西,类似于一个钩子吧,就是通过这个invoker来调用Unsafe类来进行事件操作的。
    在这里插入图片描述
    可以看到HeadHandler类:
    包括绑定,连接,关闭,读写等操作,都是调用unsafe来操作的。
    Unsafe是啥:CAS文中有提到Unsafe,用来调用本地代码。
    在这里插入图片描述

Netty之Java I/O演进之路(一)
Netty之NIO入门(二)
Netty之Netty入门应用(三)
Netty之TCP粘包/拆包问题(四)
Netty之编解码开发(五)
Netty之ChannelPipeline(六)
Netty之EventLoop和EventLoopGroup(七)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小丸子呢

致力于源码分析,期待您的激励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值