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

设计模式——责任链模式(Chain of Responsibility Pattern)+ Spring相关源码

文章目录

  • 一、责任链模式定义
  • 二、例子
    • 2.1 菜鸟教程
      • 2.1.1 定义一个抽象日志类
      • 2.1.2 定义日志类的具体实现类ConsoleLogger 、ErrorLogger 、FileLogger
      • 2.1.3 将日志类串起来,并使用
    • 2.2 JDK源码——Filter
    • 2.3 Spring源码——HandlerInterceptor
  • 三、其他设计模式

一、责任链模式定义

类型: 行为型模式
每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
目的: 职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

个人理解:上面菜鸟教程说职责链将发送者和请求的处理者解耦,但个人觉得职责链更多的是将多个责任解耦,使用时将所需要的责任组织成责任链。

二、例子

2.1 菜鸟教程

菜鸟教程是以一个日志类为例子。

2.1.1 定义一个抽象日志类

public abstract class AbstractLogger {public static int INFO = 1;public static int DEBUG = 2;public static int ERROR = 3;protected int level;//责任链中的下一个元素protected AbstractLogger nextLogger;public void setNextLogger(AbstractLogger nextLogger){this.nextLogger = nextLogger;}public void logMessage(int level, String message){if(this.level <= level){write(message);}if(nextLogger !=null){nextLogger.logMessage(level, message);}}abstract protected void write(String message);}

2.1.2 定义日志类的具体实现类ConsoleLogger 、ErrorLogger 、FileLogger

public class ConsoleLogger extends AbstractLogger {public ConsoleLogger(int level){this.level = level;}@Overrideprotected void write(String message) {    System.out.println("Standard Console::Logger: " + message);}
}
public class ErrorLogger extends AbstractLogger {public ErrorLogger(int level){this.level = level;}@Overrideprotected void write(String message) {    System.out.println("Error Console::Logger: " + message);}
}
public class FileLogger extends AbstractLogger {public FileLogger(int level){this.level = level;}@Overrideprotected void write(String message) {    System.out.println("File::Logger: " + message);}
}

2.1.3 将日志类串起来,并使用

public class ChainPatternDemo {private static AbstractLogger getChainOfLoggers(){AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);errorLogger.setNextLogger(fileLogger);fileLogger.setNextLogger(consoleLogger);return errorLogger;  }public static void main(String[] args) {AbstractLogger loggerChain = getChainOfLoggers();loggerChain.logMessage(AbstractLogger.INFO, "This is an information.");loggerChain.logMessage(AbstractLogger.DEBUG, "This is a debug level information.");loggerChain.logMessage(AbstractLogger.ERROR, "This is an error information.");}
}

2.2 JDK源码——Filter

public interface Filter {default void init(FilterConfig filterConfig) throws ServletException {}void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;default void destroy() {}
}

2.3 Spring源码——HandlerInterceptor

public interface HandlerInterceptor {default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return true;}default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {}default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {}
}
public class HandlerExecutionChain {@Nullableprivate HandlerInterceptor[] interceptors;boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {HandlerInterceptor[] interceptors = getInterceptors();if (!ObjectUtils.isEmpty(interceptors)) {for (int i = 0; i < interceptors.length; i++) {HandlerInterceptor interceptor = interceptors[i];if (!interceptor.preHandle(request, response, this.handler)) {triggerAfterCompletion(request, response, null);return false;}this.interceptorIndex = i;}}return true;}void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {HandlerInterceptor[] interceptors = getInterceptors();if (!ObjectUtils.isEmpty(interceptors)) {for (int i = interceptors.length - 1; i >= 0; i--) {HandlerInterceptor interceptor = interceptors[i];interceptor.postHandle(request, response, this.handler, mv);}}}void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)throws Exception {HandlerInterceptor[] interceptors = getInterceptors();if (!ObjectUtils.isEmpty(interceptors)) {for (int i = this.interceptorIndex; i >= 0; i--) {HandlerInterceptor interceptor = interceptors[i];try {interceptor.afterCompletion(request, response, this.handler, ex);}catch (Throwable ex2) {logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);}}}}
}

三、其他设计模式

创建型模式
结构型模式

  • 1、设计模式——装饰器模式(Decorator Pattern)+ Spring相关源码

行为型模式

  • 1、设计模式——访问者模式(Visitor Pattern)+ Spring相关源码
  • 2、设计模式——中介者模式(Mediator Pattern)+ JDK相关源码
  • 3、设计模式——策略模式(Strategy Pattern)+ Spring相关源码
  • 4、设计模式——状态模式(State Pattern)
  • 5、设计模式——观察者模式(Observer Pattern)+ Spring相关源码
  • 6、设计模式——备忘录模式(Memento Pattern)
  • 7、设计模式——模板方法模式(Template Pattern)+ Spring相关源码
  • 8、设计模式——迭代器模式(Iterator Pattern)+ Spring相关源码

相关文章:

设计模式——责任链模式(Chain of Responsibility Pattern)+ Spring相关源码

文章目录 一、责任链模式定义二、例子2.1 菜鸟教程2.1.1 定义一个抽象日志类2.1.2 定义日志类的具体实现类ConsoleLogger 、ErrorLogger 、FileLogger2.1.3 将日志类串起来&#xff0c;并使用 2.2 JDK源码——Filter2.3 Spring源码——HandlerInterceptor 三、其他设计模式 一、…...

游戏中的随机抽样算法

相关题目&#xff1a; 382. 链表随机节点 384. 打乱数组 398. 随机数索引 文章详解&#xff1a; 游戏中的随机抽样算法 class ListNode:def __init__(self, val0, nextNone):self.val valself.next nextclass RandListNode:"""382. 链表随机节点https://lee…...

【Qt之QtXlsx模块】安装及使用

1. 安装Perl&#xff0c;编译QtXlsx源码用 可以通过命令行进行查看是否已安装Perl。 下载及安装传送门&#xff1a;链接: https://blog.csdn.net/MrHHHHHH/article/details/134233707?spm1001.2014.3001.5502 1.1 未安装 命令&#xff1a;perl --version 显示以上是未安装…...

如何在 TFRecord 文件上训练 Keras 模型实现黑色素瘤分类器

简介 + 设置 TFRecords 存储一系列二进制记录,线性读取。它们是存储数据的有用格式,因为它们可以有效地读取。在此处了解有关 TFRecords 的更多信息 。 我们将探索如何轻松加载黑色素瘤分类器的 TFRecords。 import tensorflow as tf from functools import partial import…...

C++ 复制控制之复制构造函数

C类用三个特殊的成员函数&#xff1a;复制构造函数、赋值操作符和析构函数 来决定类对象之间的初始化或赋值时发生什么。所谓的“复制控制”即通过这三个成员函数控制对象复制的过程 复制构造函数首先是一个构造函数&#xff0c;它同所有其他的构造函数一样与类同名&#xff0…...

Windows ObjectType Hook 之 ParseProcedure

1、背景 Object Type Hook 是基于 Object Type的一种深入的 Hook&#xff0c;比起常用的 SSDT Hook 更为深入。 有关 Object Type 的分析见文章 《Windows驱动开发学习记录-ObjectType Hook之ObjectType结构相关分析》。 这里进行的 Hook 为 其中之一的 ParseProcedure。文章实…...

下载树莓派对应的64位Ubuntu系统步骤

说点废话&#xff1a;因为ros2需要安装在64位Ubuntu上面&#xff0c;所以安装64位最合适&#xff1b; 第一步打开https://cn.ubuntu.com/ 网站&#xff1b;选择下载--->iot----> 选择这个镜像文件下载。我觉得镜像文件是img格式的&#xff0c;跟iso文件区别是&#xff…...

网络运维Day03

文章目录 基本命令使用查看文本文件内容-cat命令分页查看文本文件-less命令查看CPU信息-lscpu命令查看系统内核版本-uname命令查看机修改主机名-hostname命令查看IP地址-ifconfig命令创建目录-mkdir命令创建空文件-touch命令查看文件前几行-head命令查看文件后几行-tail命令快速…...

LangChain+LLM实战---ChatGPT的工作原理

一个词一个词的输出 ChatGPT能够自动生成类似于人类书写的文本&#xff0c;这是非常了不起和出乎意料的。但它是如何做到的&#xff1f;为什么会有效果呢&#xff1f;我的目的在于大致概述ChatGPT内部发生了什么&#xff0c;然后探讨它为什么能够很好地生成我们认为有意义的文…...

Appium知多少

Appium我想大家都不陌生&#xff0c;这是主流的移动自动化工具&#xff0c;但你对它真的了解么&#xff1f;为什么很多同学搭建环境时碰到各种问题也而不知该如何解决。 appium为什么英语词典查不到中文含义&#xff1f; appium是一个合成词&#xff0c;分别取自“applicatio…...

【实战Flask API项目指南】之五 RESTful API设计

实战Flask API项目指南之 RESTful API设计 本系列文章将带你深入探索实战Flask API项目指南&#xff0c;通过跟随小菜的学习之旅&#xff0c;你将逐步掌握 Flask 在实际项目中的应用。让我们一起踏上这个精彩的学习之旅吧&#xff01; 前言 当小菜踏入Flask后端开发的世界时…...

尚硅谷大数据项目《在线教育之实时数仓》笔记005

视频地址&#xff1a;尚硅谷大数据项目《在线教育之实时数仓》_哔哩哔哩_bilibili 目录 第9章 数仓开发之DWD层 P031 P032 P033 P034 P035 P036 P037 P038 P039 P040 第9章 数仓开发之DWD层 P031 DWD层设计要点&#xff1a; &#xff08;1&#xff09;DWD层的设计依…...

算法通过村第十八关-回溯|青铜笔记|什么叫回溯(中篇)

文章目录 前言回溯的核心问题撤销操作解释总结 前言 提示&#xff1a;阳光好的时候&#xff0c;会感觉还可以活很久&#xff0c;甚至可以活出喜悦。 --余秀华 回溯是非常重要的算法思想之一&#xff0c;主要解决一些暴力枚举也搞不定的问题&#xff08;这里埋个坑&#x1f4a3;…...

generate by chatgpt:应用上线前的checkList(部分是我自己的回答)

prompt 1 想象你是一名高级测试工程师&#xff0c;在应用上线前你需要提供一份checklist,请写出来: 作为一名高级测试工程师&#xff0c;以下是我在应用上线前的检查清单&#xff1a; 功能性测试&#xff1a; 检查所有要素和功能是否正常工作。确保满足了所有用户故事/需求。…...

Redis实战 | 使用Redis 的有序集合(Sorted Set)实现排行榜功能,和Spring Boot集成

专栏集锦&#xff0c;大佬们可以收藏以备不时之需 Spring Cloud实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏&#xff1a;https:/…...

基于信号功率谱特征和GRNN广义回归神经网络的信号调制类型识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ................................................................ %调制识别 len1 func_f…...

matplotlib从起点出发(10)_Tutorial_10_Layout

使用受约束的绘图干净整洁地将图形合适排列。 受约束的布局会自动调整子图&#xff0c;以便刻度标签、图例和颜色条等装饰不会重叠&#xff0c;同时仍保留用户请求的逻辑布局。 受约束布局类似于“紧密布局”&#xff0c;但它要更灵活。它处理放置在多个轴上的Axes(放置颜色条…...

HTTP头部信息解释分析(详细整理)(转载)

这篇文章为大家介绍了HTTP头部信息&#xff0c;中英文对比分析&#xff0c;还是比较全面的&#xff0c;若大家在使用过程中遇到不了解的&#xff0c;可以适当参考下 HTTP 头部解释 1. Accept&#xff1a; 告诉WEB服务器自己接受什么介质类型&#xff0c;/ 表示任何类型&#…...

集线器、交换机、网桥、路由器、网关

目录 集线器(HUB)交换机(SWITCH)网桥(BRIDGE)路由器(ROUTER)网关(GATEWAY)交换机和路由器的区别参考 集线器(HUB) 功能 集线器对数据的传输起到同步、放大和整形的作用 属于物理层设备 工作机制 使用集线器互连而成的以太网被称为共享式以太网。当某个主机要给另一个主机发送单…...

项目实战:新增@Controller和@Service@Repository@Autowire四个注解

1、Controller package com.csdn.mymvc.annotation; import java.lang.annotation.*; Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Inherited public interface Controller { }2、Service package com.csdn.mymvc.annotation; import java.lang.annotation.*…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...