当前位置: 首页 > news >正文

ChannelPipeline

概述

  对于一个请求,可能会需要很多的处理逻辑,如果把所有的处理逻辑都放在一个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

相关文章:

  • 你需要的物流运输类报表,都在这里
  • 本地Navicat远程连接Centos7服务器出现的错误汇总
  • 转载一篇让你全面了解什么是.NET。
  • Java设计模式: 单例模式
  • webpack4.0介绍与使用(一)
  • Java 8中处理集合的优雅姿势——Stream
  • Linux上部署Springboot相关命令
  • ArrayList中的ConcurrentModificationException,并发修改异常,fail-fast机制。
  • vue-cli从2升级到3报错error 404 Not Found: @wry/context@^0.4.0
  • 创建数据结构库基础设施——异常类的构建
  • Windows下SVN的下载、安装
  • centOS7网络配置
  • angularJS 自定义服务
  • JqGrid纵向合并单元格
  • 线程池之ThreadPoolExecutor线程池源码分析笔记
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • angular组件开发
  • Docker容器管理
  • Java 内存分配及垃圾回收机制初探
  • JavaScript 奇技淫巧
  • Javascript弹出层-初探
  • Laravel 菜鸟晋级之路
  • Linux各目录及每个目录的详细介绍
  • PHP变量
  • SQL 难点解决:记录的引用
  • Wamp集成环境 添加PHP的新版本
  • Webpack 4 学习01(基础配置)
  • zookeeper系列(七)实战分布式命名服务
  • 半理解系列--Promise的进化史
  • 分布式熔断降级平台aegis
  • 项目管理碎碎念系列之一:干系人管理
  • 原生js练习题---第五课
  • 智能网联汽车信息安全
  • 自动记录MySQL慢查询快照脚本
  • Java性能优化之JVM GC(垃圾回收机制)
  • ​2020 年大前端技术趋势解读
  • ​力扣解法汇总946-验证栈序列
  • #include
  • #laravel 通过手动安装依赖PHPExcel#
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (转)fock函数详解
  • (转)程序员疫苗:代码注入
  • (转)人的集合论——移山之道
  • .java 9 找不到符号_java找不到符号
  • .NET Core WebAPI中封装Swagger配置
  • .NET Core 中插件式开发实现
  • .NET 的程序集加载上下文
  • .NET/C# 项目如何优雅地设置条件编译符号?
  • /usr/bin/env: node: No such file or directory
  • @ResponseBody
  • [2019.3.20]BZOJ4573 [Zjoi2016]大森林
  • [Android]创建TabBar