netty源码分析之ChannelHandler

本文深入探讨Netty中ChannelHandler的重要作用及其实现原理。详细分析了DefaultChannelHandlerContext的内部结构,包括其链表结构、关键属性及如何处理上下游事件。

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

netty里面最重要的应该是ChannelHandler,这个里面也是用户编程直接打交道的接口,也是串行于ChannelPipeLine里面执行相应的业务逻辑。



        从类结构来看,一个handler应该有一个ChannelHandlerContext,ChannelHandler是处在上层的一个标识接口,下面有两个接口分别来处理Upstream event和一个Downstream event。

        ChannelHandler比较好理解,我们重点来看DefaultChannelHandlerContext的实现类。

       

Java代码   收藏代码
  1. volatile DefaultChannelHandlerContext next;  
  2.         volatile DefaultChannelHandlerContext prev;  
  3.         private final String name;  
  4.         private final ChannelHandler handler;  
  5.         private final boolean canHandleUpstream;  
  6.         private final boolean canHandleDownstream;  
  7.         private volatile Object attachment;  

         在这个里面,可以看到有个链表结构,next、prev分别有指向前一个和后一个的HandlerContext,一个是handlerContext的名称,一个是handler就是里面的handler对象,两个变量用来标识是否可以处理upstream和downstream事件的能力,最后一个是attachment,里面放的是handler里面可以传递的一些共享变量信息。

        

Java代码   收藏代码
  1. DefaultChannelHandlerContext(  
  2.                DefaultChannelHandlerContext prev, DefaultChannelHandlerContext next,  
  3.                String name, ChannelHandler handler) {  
  4.   
  5.            if (name == null) {  
  6.                throw new NullPointerException("name");  
  7.            }  
  8.            if (handler == null) {  
  9.                throw new NullPointerException("handler");  
  10.            }  
  11.            canHandleUpstream = handler instanceof ChannelUpstreamHandler;  
  12.            canHandleDownstream = handler instanceof ChannelDownstreamHandler;  
  13.   
  14.   
  15.            if (!canHandleUpstream && !canHandleDownstream) {  
  16.                throw new IllegalArgumentException(  
  17.                        "handler must be either " +  
  18.                        ChannelUpstreamHandler.class.getName() + " or " +  
  19.                        ChannelDownstreamHandler.class.getName() + '.');  
  20.            }  
  21.   
  22.            this.prev = prev;  
  23.            this.next = next;  
  24.            this.name = name;  
  25.            this.handler = handler;  
  26.        }  

             构造函数也很容易理解,在初始化的时候就将next和prev传递过来了,同时初始化了handler和name,以及根据handler的性质是否可以来处理相关的event。

           我们来看sendDownstream和sendUpstream的实现吧。

       

Java代码   收藏代码
  1. public void sendDownstream(ChannelEvent e) {  
  2.            DefaultChannelHandlerContext prev = getActualDownstreamContext(this.prev);  
  3.            if (prev == null) {  
  4.                try {  
  5.                    getSink().eventSunk(DefaultChannelPipeline.this, e);  
  6.                } catch (Throwable t) {  
  7.                    notifyHandlerException(e, t);  
  8.                }  
  9.            } else {  
  10.                DefaultChannelPipeline.this.sendDownstream(prev, e);  
  11.            }  
  12.        }  

             从这个代码来看,通过getActualDownstreamContext顺着prev链条超前找,找到前一个可以处理downstream的handlerContext,然后开始执行,如果找不到就交给Sink来处理,从这里来看也能体会到一点handler和sink自己的一些关系,作者将这个抽象成两个组件来处理确实比较厉害。

             同理我们也可以猜到upstream事件的处理逻辑,找到最后一个handler然后一点一点的处理。

            

Java代码   收藏代码
  1. public void sendUpstream(ChannelEvent e) {  
  2.             DefaultChannelHandlerContext next = getActualUpstreamContext(this.next);  
  3.             if (next != null) {  
  4.                 DefaultChannelPipeline.this.sendUpstream(next, e);  
  5.             }  
  6.         }  

 

            

### Netty 源码分析文章汇总 对于希望深入了解Netty源码的读者来说,一系列深入浅出的文章能够提供极大的帮助。以下是按照不同主题整理的一系列关于Netty源码解析的文章列表[^1]: #### 1. 初识Netty - **Netty入门**:介绍了Netty的基础概念及其优势所在。 #### 2. 核心组件剖析 - **Netty架构设计**:探讨了Netty的整体框架设计理念。 - **Channel详解**:解释了`Channel`接口的作用以及其实现方式。 - **ChannelHandler介绍**:描述了如何利用`ChannelHandler`处理网络事件。 - **ChannelPipeline**:讲述了消息传递过程中所经过的管道机制。 #### 3. 数据传输优化 - **字节缓冲区 ByteBuf(上下篇)**:详细解读了高效内存管理工具`ByteBuf`的工作原理。 - **Netty如何实现零拷贝**:讨论了减少数据复制开销的技术细节。 #### 4. 应用层协议支持 - **编程引导类 Bootstrap**:指导用户快速搭建基于Netty的应用程序。 - **Reactor模型**:阐述了异步I/O多路复用技术在Netty中的应用。 - **编解码器系列** - **编码器/解码器基础** - **自定义编解码器** #### 5. 启动流程揭秘 - **Server端启动过程源码分析**:逐步拆解服务器实例初始化直至监听端口绑定完成的关键步骤[^5]。 这些资源不仅适合初学者学习掌握基础知识,同时也非常适合有一定经验的研发人员进一步挖掘更深层次的功能特性。 ```java // 示例代码片段展示了NioServerSocketChannel的部分构造逻辑 public class NioServerSocketChannel extends AbstractNioMessageChannel { private final ServerSocketChannel javaChannel; public NioServerSocketChannel() throws ExceptionInInitializerError { this(ServerSocketChannel.open()); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值