适用场景:

  • 对于一个请求来说,如果有个对象都有机会处理它,而且不明确到底是哪个对象会处理请求时,我们可以考虑使用责任链模式实现它,让请求从链的头部往后移动,直到链上的一个节点成功处理了它为止

优点:

  • 发送者不需要知道自己发送的这个请求到底会被哪个对象处理掉,实现了发送者和接受者的解耦
  • 简化了发送者对象的设计
  • 可以动态的添加节点和删除节点

缺点:

  • 所有的请求都从链的头部开始遍历,对性能有损耗
  • 极差的情况,不保证请求一定会被处理

自定义一个责任链

在java中不再存在指针了,如果我们想创建一个链表,只能是在本类中添加本类属性, 因为我们想创建一个链表,所以这是必须的工作

需要提供set方法,让当前的节点可以设置自己的下一个节点

处理请求的逻辑,设计成抽象方法,让不同的节点根据自己的需求去实现

public abstract class Approver {
Approver approver;
String name;
// todo 抽象父类中可以存在构造函数,但是当我们创建子类时,必须要有一个参数的构造函数,
// todo 让子类一个参数的构造函数,来给这个函数初始化
public Approver (String name){
this.name=name;
} public abstract void ProcessRequest(PurchaseRequest request); // 如果当前的处理器处理不了,就会往下传播
public void setApprover( Approver approver){
this.approver=approver;
}
}

PurchaseRequest,需要被处理的请求,根据自己的需要各不相同

接着就是链表上的不同功能的节点都要实现上面的抽象类Approver,重写它的抽象方法,添加上他们特定的功能

测试:

    // 创建出各个节点
Approver1 approver1 = new Approver1();
Approver2 approver2 = new Approver2();
Approver3 approver3 = new Approver3(); // 设置他们关系
approver1.setApprover(approver2);
approver2.setApprover(approver3); // 发起请求
Client client = new Client();
PurchaseRequest purchaseRequest = client.sendRequest(); // 处理请求
tom.ProcessRequest(purchaseRequest);

把请求传递给责任链的第一个节点,她会自动往后传播下去,直到有一个节点成功处理了它

Netty的责任链设计

netty的pipeline设计,就采用了责任链设计模式, 底层采用双向链表的数据结构, 将链上的各个处理器串联起来

客户端每一个请求的到来,netty都认为,pipeline中的所有的处理器都有机会处理它,因此,对于入栈的请求,全部从头节点开始往后传播,一直传播到尾节点(来到尾节点的msg会被释放掉)

netty的责任链模式中的组件

  • 责任处理器接口

    • pipeline中的处理器都它的具体实现
  • 添加删除责任处理器的接口
  • 上下文
    • 通过这个上下文,可以获得需要的数据,属性
  • 责任终止机制
    • pipeline中的每一个节点,都可以终止事件的传播

netty的责任处理器接口

责任处理器接口, pipeline中的所有的handler的顶级抽象接口,它规定了所有的handler统一要有添加,移除,异常捕获的行为

public interface ChannelHandler {

// todo 当handler被添加到真实的上下文中,并且准备处理事件时被调用
// todo handler 被添加进去的回调
void handlerAdded(ChannelHandlerContext ctx) throws Exception; // todo 是 handler 被移出的后的 回调
void handlerRemoved(ChannelHandlerContext ctx) throws Exception; @Deprecated
void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception; @Inherited
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Sharable {
// no value
}
}

netty对责任处理接口,做了更细粒度的划分, 处理器被分成了两种, 一种是站处理器ChannelInboundHandler,另一种是出站处理器ChannelOutboundHandler,这两个接口都继承自ChannelHandler

添加删除责任处理器的接口

netty中所有的处理器最终都在添加在pipeline上,所以,添加删除责任处理器的接口的行为 netty在channelPipeline中的进行了规定

public interface ChannelPipeline
extends ChannelInboundInvoker, ChannelOutboundInvoker, Iterable<Entry<String, ChannelHandler>> { ChannelPipeline addFirst(String name, ChannelHandler handler); ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler); ChannelPipeline addLast(String name, ChannelHandler handler); ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler); ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler); ...

上下文

pipeline中的handler被封装进了上下文中,如下, 通过上下文,可以轻松拿到当前节点所属的channel, 以及它的线程执行器

// todo AttributeMap -- 让ChannelHandlerContext 可以存储自定义的属性
// todo ChannelInboundInvoker -- 让ChannelHandlerContext 可以进行 InBound事件的传播,读事件,read 或者是 注册事件 active事件
// todo ChannelOutboundInvoker -- 让ChannelHandlerContext 可以传播写事件
public interface ChannelHandlerContext extends AttributeMap, ChannelInboundInvoker, ChannelOutboundInvoker { // todo 获取ChannelHandlerContext所对应的这个Channel对象
Channel channel(); // todo 获取事件执行器
EventExecutor executor();
...

责任终止机制

责任终止机制

  • 在pipeline中的任意一个节点,只要我们不手动的往下传播下去,这个事件就会终止传播在当前节点
  • 对于入站数据,默认会传递到尾节点,进行回收,如果我们不进行下一步传播,事件就会终止在当前节点,别忘记回收msg
  • 对于出站数据,用header节点的使用unsafe对象,把数据写会客户端也意味着事件的终止

事件的传播

底层事件的传播使用的就是针对链表的操作

private AbstractChannelHandlerContext findContextInbound() {
AbstractChannelHandlerContext ctx = this;
do {
ctx = ctx.next;
} while (!ctx.inbound);
return ctx;
}

Netty中的责任链模式的更多相关文章

  1. Java网络编程--Netty中的责任链

    Netty中的责任链 设计模式 - 责任链模式 责任链模式(Chain of Responsibility Pattern)是一种是行为型设计模式,它为请求创建了一个处理对象的链.其链中每一个节点都看 ...

  2. 网络编程Netty入门:责任链模式介绍

    目录 责任链模式 责任链模式的简单实现 Netty中的ChannelPipeline责任链 服务端接收客户端连接 pipeline初始化 入站事件和出站事件 Pipeline中的Handler Pip ...

  3. Python使用设计模式中的责任链模式与迭代器模式的示例

    Python使用设计模式中的责任链模式与迭代器模式的示例 这篇文章主要介绍了Python使用设计模式中的责任链模式与迭代器模式的示例,责任链模式与迭代器模式都可以被看作为行为型的设计模式,需要的朋友可 ...

  4. 如何在C#/.NET Core中使用责任链模式

    原文:Chain Of Responsbility Pattern In C#/.NET Core 作者:Wade 译者:Lamond Lu 最近我有一个朋友在研究经典的"Gang Of F ...

  5. JAVA中的责任链模式(CH01)

    责任链模式的关键在于每一个任务处理者都必须持有下一个任务处理者的作用 纯的责任链:纯的责任链是只能也必须只有一个任务处理者去处理这个任务,       不会出现没有处理者处理的情况,也不会出现有多个处 ...

  6. JAVA中的责任链模式(CH02)

    对责任链CH01做出优化,解决耦合度太高问题 记得上一篇我们使用的是抽象类,然后用子类去继承的方法实现等级的桥接,从而发现了耦合度太高. 为了解决这个问题. 我们本次使用接口进行抽象,然后使用到一个” ...

  7. Spring是如何使用责任链模式的?

    关于责任链模式,其有两种形式,一种是通过外部调用的方式对链的各个节点调用进行控制,从而进行链的各个节点之间的切换. 另一种是链的每个节点自由控制是否继续往下传递链的进度,这种比较典型的使用方式就是Ne ...

  8. 责任链模式/chain of responsibility/行为型模式

    职责链模式 chain of responsibility 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处 ...

  9. 编写计算器程序学习JS责任链模式

    设计模式中的责任链模式能够很好的处理程序过程的逻辑判断,提高程序可读性. 责任链模式的核心在于责任链上的元素判断能够处理该数据,不能处理的话直接交给它的后继者. 计算器的基本样式: 通过div+css ...

随机推荐

  1. c# 向驱动打印机发送命令打开钱箱

    引用的dll 链接: https://pan.baidu.com/s/1MjwmfvBCPTBq1QNapKzDmg 提取码: 9wuf [DllImport("Drawcash.dll&q ...

  2. 利用消息机制实现VC与Delphi之间的通讯(发送自定义消息)

    摘要: 本文介绍了使用Windows消息机制实现由不同语言编制的程序之间的相互通讯.联系,并以当前较为流行的两种语言Microsoft Visual C++ 6.0和Borland delphi 5. ...

  3. UITableViewStyleGrouped 设置表头出现section不为0的问题

    UITableViewStyleGrouped 设置表头出现section不为0的问题 1.如果使用UITableViewStylePlain样式的表格,那么header是会在表格滑动的时候在顶部悬浮 ...

  4. 源码解读·RT-Thread多任务调度算法

    *本文依据RT-Thread当时最新版本4.0.1版本源码 RT-Thread操作系统是一款基于优先级和时间片轮转的多任务实时操作系统.其调度算法采用256个优先级,并支持相同优先级的任务存在.不同优 ...

  5. epoll模型的探索与实践

    我们知道nginx的效率非常高,能处理上万级的并发,其之所以高效离不开epoll的支持, epoll是什么呢?,epoll是IO模型中的一种,属于多路复用IO模型; 到这里你应该想到了,select, ...

  6. Quartz.Net实现作业定时调度详解

    1.Quartz.NET介绍 Quartz.NET是一个强大.开源.轻量的作业调度框架,你能够用它来为执行一个作业而创建简单的或复杂的作业调度.它有很多特征,如:数据库支持,集群,插件,支持cron- ...

  7. Adam和学习率衰减(learning learning decay)

    目录 梯度下降法更新参数 Adam 更新参数 Adam + 学习率衰减 Adam 衰减的学习率 References 本文先介绍一般的梯度下降法是如何更新参数的,然后介绍 Adam 如何更新参数,以及 ...

  8. NSCache缓存怎么来的

    什么是NSCache NSCache主要用来存储临时数据(键值对),当内存资源不够时,系统会自动释放部分数据.它有三个特点: • NSCache为了保持不占用过多的系统内存,它有多种自动回收内存策略: ...

  9. 使用 python 提取照片中的手机信息

    使用 python 提取照片中的手机信息 最近在做一个项目,有一个很重要的点是需要获取使用用户的手机信息,这里我选择从照片中获取信息.有人会问为什么不从手机里面直接获取设备信息.由于现在android ...

  10. 微信小程序商城(Java版)

    体验 后台演示地址(账号:admin 密码:admin) 小程序体验如下: 技术选型 1 后端使用技术 1.1 springframework4.3.7.RELEASE 1.2 mybatis3.1. ...