netty源码分析之ChannelHandler

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



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

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

       

volatile DefaultChannelHandlerContext next;
        volatile DefaultChannelHandlerContext prev;
        private final String name;
        private final ChannelHandler handler;
        private final boolean canHandleUpstream;
        private final boolean canHandleDownstream;
        private volatile Object attachment;

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

        

 DefaultChannelHandlerContext(
                DefaultChannelHandlerContext prev, DefaultChannelHandlerContext next,
                String name, ChannelHandler handler) {

            if (name == null) {
                throw new NullPointerException("name");
            }
            if (handler == null) {
                throw new NullPointerException("handler");
            }
            canHandleUpstream = handler instanceof ChannelUpstreamHandler;
            canHandleDownstream = handler instanceof ChannelDownstreamHandler;


            if (!canHandleUpstream && !canHandleDownstream) {
                throw new IllegalArgumentException(
                        "handler must be either " +
                        ChannelUpstreamHandler.class.getName() + " or " +
                        ChannelDownstreamHandler.class.getName() + '.');
            }

            this.prev = prev;
            this.next = next;
            this.name = name;
            this.handler = handler;
        }

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

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

       

 public void sendDownstream(ChannelEvent e) {
            DefaultChannelHandlerContext prev = getActualDownstreamContext(this.prev);
            if (prev == null) {
                try {
                    getSink().eventSunk(DefaultChannelPipeline.this, e);
                } catch (Throwable t) {
                    notifyHandlerException(e, t);
                }
            } else {
                DefaultChannelPipeline.this.sendDownstream(prev, e);
            }
        }

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

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

            

public void sendUpstream(ChannelEvent e) {
            DefaultChannelHandlerContext next = getActualUpstreamContext(this.next);
            if (next != null) {
                DefaultChannelPipeline.this.sendUpstream(next, e);
            }
        }

 

            

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值