博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ChannelPipeline
阅读量:5013 次
发布时间:2019-06-12

本文共 2500 字,大约阅读时间需要 8 分钟。

概述

  对于一个请求,可能会需要很多的处理逻辑,如果把所有的处理逻辑都放在一个ChannelHandler中,那么代码会十分的臃肿,因此需要把逻辑放在不同的ChannelHandler中实现面向对象的单一职责原则。Netty使用责任链模式把负责不同逻辑的ChannelHandler组合在一起,ChannelPipeline就是ChannelHandler的容器,每一个新建的Channel,Netty都会自动为之分配一个新的ChannelPipeline,这种分配是自动的,且这种绑定在netty整个生命周期中是永久性的。ChannelPipeline会负责Channel所有事件的处理。

  ChannelPipeline会按照相反的顺序调用ChannelHandler处理入栈和出栈事件。

  

 

  

 

源码  

addBefor

  把名称为name的handler添加到baseName的前面,调用了一个重载的方法。

@Override    public final ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler) {        return addBefore(null, baseName, name, handler);    }

  group传入的是null,不需要考虑。

  • 首先注意到整个代码用synchronized包裹起来,说明这是ChannelPipe是一个线程安全的对象,这是因为netty允许在运行时候动态修改ChannelPipe的内容,那么就存在修改线程和正常运行线程同时访问ChannelPipe的情况,需要使用synchronized来避免潜在的线程安全问题。
  • checkMultiplicity判断handler是否可以共享,如果handler已经添加且不可共享,抛出异常。
  • 对handler的名称进行检查(filterName),如果名称重复抛出异常,如果name为Null则生成一个name。
  • 调用getContextOrDie从容器中找到baseName的handler,如这个方法名字暗示,如果没有找到就抛出异常(OrDie)。
  • 新建ChannelHandlerContext作为新handler的上下文,并添加到Pipeline里,pipeline说白了就是个双向链表,添加的方法也很简单,ChannelPipeline持有双向链表的头节点和尾节点。
@Override    public final ChannelPipeline addBefore(            EventExecutorGroup group, String baseName, String name, ChannelHandler handler) {        final AbstractChannelHandlerContext newCtx;        final AbstractChannelHandlerContext ctx;        synchronized (this) {            checkMultiplicity(handler);            name = filterName(name, handler);            ctx = getContextOrDie(baseName);            newCtx = newContext(group, name, handler);            addBefore0(ctx, newCtx);            // If the registered is false it means that the channel was not registered on an eventloop yet.            // In this case we add the context to the pipeline and add a task that will call            // ChannelHandler.handlerAdded(...) once the channel is registered.            if (!registered) {                newCtx.setAddPending();                callHandlerCallbackLater(newCtx, true);                return this;            }            EventExecutor executor = newCtx.executor();            if (!executor.inEventLoop()) {                newCtx.setAddPending();                executor.execute(new Runnable() {                    @Override                    public void run() {                        callHandlerAdded0(newCtx);                    }                });                return this;            }        }        callHandlerAdded0(newCtx);        return this;    }

 

 

转载于:https://www.cnblogs.com/AshOfTime/p/10903044.html

你可能感兴趣的文章
构造方法和全局变量的关系
查看>>
python3基础05(有关日期的使用1)
查看>>
ArrayList的使用方法
查看>>
面向对象高级
查看>>
Bitwise And Queries
查看>>
打印Ibatis最终的SQL语句
查看>>
HBase之八--(3):Hbase 布隆过滤器BloomFilter介绍
查看>>
oracle连接问题ORA-00604,ORA-12705
查看>>
NOI 2019 退役记
查看>>
java的几个日志框架log4j、logback、common-logging
查看>>
Java从零开始学十三(封装)
查看>>
Python2和Python3中的rang()不同之点
查看>>
MySQL的外键,修改表,基本数据类型,表级别操作,其他(条件,通配符,分页,排序,分组,联合,连表操作)...
查看>>
UVALive 4128 Steam Roller 蒸汽式压路机(最短路,变形) WA中。。。。。
查看>>
记忆--1.致我们不可缺少的记忆
查看>>
lintcode28- Search a 2D Matrix- easy
查看>>
react项目
查看>>
C# 万年历 农历 节气 节日 星座 星宿 属相 生肖 闰年月 时辰(转)
查看>>
A Simple Tree Problem
查看>>
Modular Inverse [ZOJ 3609]
查看>>