java netty之DefaultChannelHandlerContext

本文介绍了Netty中的DefaultChannelHandlerContext,它是handler调用的中介,负责管理handler处理的数据。文章探讨了其在pipeline和handlercontext继承体系中的角色,特别是inboundInvoker和outboundInvoker。还详细讨论了ChannelHandlerContext接口的主要方法以及DefaultChannelHandlerContext的重要属性,如executor。最后,文章简单分析了其中一个方法,并预告后续将进一步深入分析。

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

在进一步分析pipeline以及handler之前,有必要先看一下handlercontext的定义,在netty中,handler的调用都不是直接的,而是通过handlercontext间接进行的,而且handlercontext为这些handler管理了处理的数据,毕竟java没有javascript闭包那么方便,所以变量这写需要进行额外的维护。。。。。

还是按照惯例,先看看DefaultChannelHandlerContext的继承体系:


这里感觉比较奇怪的是,在pipeline和handlercontext的继承体系中都有inboundinvokeer和outboundinvoker。。。

首先来看看看ChannelHandlerContext接口的定义:

其实很简单,一些主要的方法有:

	//返回当前所属的channel
    Channel channel();
    //返回当前用于执行的executor,一般情况下是channel注册到的evetLoop
    EventExecutor executor();
然后就还有一些对buffer的操作的方法,例如是否有buffer,得到buffer,访问下一个handler的buffer等。这里就不列出来了。。。


好了,接下来来看具体的实现类DefaultChannelHandlerContext,反正现在在netty源码里面看到的基本上都是用的它,先看看它的一些重要的属性吧:

    volatile DefaultChannelHandlerContext next;   //指向后面的那一个handlercontext
    volatile DefaultChannelHandlerContext prev;    //指向前面的哪一个handlercontext

    private final Channel channel;     //所属的channel
    private final DefaultChannelPipeline pipeline;     //所属的pipeline
    private final String name;       //名字  
    private final ChannelHandler handler;    //包含的handler

    // Will be set to null if no child executor should be used, otherwise it will be set to the
    // child executor.
    final EventExecutor executor;    //所属的executor
    private ChannelFuture succeededFuture; 

    private final MessageBuf<Object> inMsgBuf;   //用于存储进来的数据的buffer,这类事msgbuf
    private final ByteBuf inByteBuf;      //有可能是bytebuf
    private MessageBuf<Object> outMsgBuf;    //如果包裹的是outboundhandler那么会有outbuffer
    private ByteBuf outByteBuf;
在netty的pipeline中,将所有的handlercontext都链成了链表,context里有next和prev引用,用于访问该链表。。

这里还有executor属性,也就是用处执行当前handler的executor,不过它一般都是空的,而是直接在channel所属的eventLoop中执行。。

由于它定义的方法比较多,而且现在就说可能不太合适,就先分析一个其中的方法吧:

    @Override
    //当已经有数据从nio的channel中读取进来的时候,会调用该方法,用于处理读取进来的数据
    public ChannelHandlerContext fireInboundBufferUpdated() {
        EventExecutor executor = executor();  //用于获取执行代码的executor,其实一般情况下就是当前channel所属的eventLoop
        if (executor.inEventLoop()) {      //如果executor就是当前的eventLoop,那么就直接执行好了否则的话需要向executor提交任务
            fireInboundBufferUpdated0(findContextInbound());
        } else {
            Runnable task = fireInboundBufferUpdated0Task;
            if (task == null) {
                fireInboundBufferUpdated0Task = task = new Runnable() {
                    @Override
                    public void run() {
                        fireInboundBufferUpdated0(findContextInbound());
                    }
                };
            }
            executor.execute(task);
        }
        return this;
    }
这个方法在inboundinvoker中定义的,是当已经有数据读取进来了之后会调用的。。。


好了,这里handlercontext基本的东西就讲的差不多了,以后的文章会进行更进一步的分析。。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值