java设计模式学习之【责任链模式】
文章目录
- 引言
- 责任链模式简介
- 定义与用途
- 实现方式
- 使用场景
- 优势与劣势
- 在Spring框架中的应用
- 日志示例
- 代码地址
引言
在现实生活中,常常会遇到这样的场景:一个请求或命令需要经过多个层级的处理。例如,一个行政审批流程可能需要通过多个部门的审核。在软件开发中,我们可以使用责任链模式来模拟这种层级处理流程。责任链模式允许我们将请求的发送者和接收者解耦,将多个处理对象连成一条链,依次处理请求。
责任链模式简介
定义与用途
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许将请求沿着处理链传递,直到一个对象处理它为止。每个处理对象都包含逻辑来处理请求或将请求传递给链上的下一个对象。
实现方式
实现责任链模式通常包括以下几个关键组件:
- 处理器接口(Handler): 定义了处理请求的接口。
- 具体处理器(Concrete Handlers): 实现处理器接口,并执行具体的处理逻辑或将请求传递给链上的下一个处理器。
- 客户端(Client): 发起请求,并将请求传递给链上的第一个处理器。
使用场景
责任链模式适用于以下场景:
- 当多个对象可以处理一个请求,但具体由哪个对象处理在运行时才确定时。
- 当想在不明确指定接收者的情况下,向多个对象中的一个提交请求时。
- 当处理请求的一组对象应被动态指定时。
例如:
- 审批流程:不同级别的审批请求通过不同级别的管理层进行处理。
- 事件处理系统:例如 GUI 中的事件传递,事件可以由多个对象处理。
- 日志记录:根据消息的严重性级别,决定将其发送到不同的输出目标。
优势与劣势
- 优势
降低耦合度:请求的发送者和接收者之间没有直接的耦合关系。
增强灵活性:可以动态地改变链内的成员或调整其顺序。
易于扩展:可以通过增加新的处理器来扩展。 - 劣势
不能保证请求一定会被接收:所有处理者都可能不处理请求,使其未被处理。
对链中请求处理者的排列顺序和数量敏感。
在Spring框架中的应用
在Spring框架中,责任链模式通常用于处理一系列的处理步骤或中间件。这种模式在Spring的多个组件中得到应用,最典型的是在Spring Security和Spring MVC中。
1. Spring Security中的责任链应用
在Spring Security中,责任链模式体现在过滤器链(Filter Chain)中。
每个请求都会通过一系列的安全过滤器,每个过滤器执行不同的安全检查和任务。这些过滤器包括:Authentication Filter:负责用户认证。
Authorization Filter:负责检查用户是否有权限访问特定资源。
Exception Translation Filter:负责处理在安全认证过程中抛出的异常。
每个过滤器处理请求后决定是否将请求传递给链中的下一个过滤器,或者是终止请求并返回响应。这正是责任链模式的核心特征。
2. Spring MVC中的责任链应用
在Spring MVC中,拦截器(Interceptors)也是一种责任链模式的体现。
拦截器用于在处理请求前后执行各种任务,比如日志记录、权限检查、事务处理等。你可以定义多个拦截器,并将它们链接在一起,形成一个拦截器链。
每个拦截器决定是否:在Controller处理请求之前执行某些操作。
在Controller处理完请求后执行某些操作。
3. Spring中的Filter Chain
Spring的另一个责任链应用是Spring Web中的Filter Chain。在Spring Web中,你可以定义多个过滤器来处理Web请求。
每个过滤器执行完任务后,可以决定是否将请求传递给链中的下一个过滤器。
这些过滤器可以处理跨站请求伪造(CSRF)保护、CORS、编码问题等。
日志示例

步骤 1:创建抽象日志类
首先定义了一个 AbstractLogger 抽象类,作为日志处理者的基类。
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:创建具体的日志处理类
创建了具体的日志处理者类,扩展了 AbstractLogger。
public class ConsoleLogger extends AbstractLogger {public ConsoleLogger(int level){this.level = level;}@Overrideprotected void write(String message) { System.out.println("标准控制台::Logger: " + message);}
}public class ErrorLogger extends AbstractLogger {public ErrorLogger(int level){this.level = level;}@Overrideprotected void write(String message) { System.out.println("错误控制台::Logger: " + message);}
}public class FileLogger extends AbstractLogger {public FileLogger(int level){this.level = level;}@Overrideprotected void write(String message) { System.out.println("文件::Logger: " + message);}
}
每个具体的处理者类负责处理特定级别的日志消息。
步骤 3:创建不同类型的日志处理者并形成链
定义了一个客户端类 ChainPatternDemo 来创建日志处理者链并使用该链处理消息。
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, "这是一条信息级别的消息。");loggerChain.logMessage(AbstractLogger.DEBUG, "这是一条调试级别的消息。");loggerChain.logMessage(AbstractLogger.ERROR, "这是一条错误级别的消息。");}
}

在这个客户端中,我们创建了不同级别的日志处理者并连接它们形成一条链。然后,我们发送不同级别的消息给责任链,可以看到消息被相应级别的处理者处理。
这个示例演示了责任链模式在处理具有不同处理级别的请求中的效力。通过改变链的结构或成员,可以灵活地改变请求处理的方式。
代码地址
23种设计模式相关代码后续会逐步提交到github上,方便学习,欢迎指点:
代码地址
https://github.com/RuofeiSun/lf-23Pattern
相关文章:
java设计模式学习之【责任链模式】
文章目录 引言责任链模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用日志示例代码地址 引言 在现实生活中,常常会遇到这样的场景:一个请求或命令需要经过多个层级的处理。例如,一个行政审批流程可能需要通过多个部门的审…...
docker 安装可视化工具 Protainer 以及 汉化
一、创建保存数据的卷 安装网址:Install Portainer BE with Docker on Linux - Portainer Documentation docker pull portainer/portainer二、根据portainer镜像创建容器 docker run -d -p 8000:8000 -p 9000:9000\ --name portainer --restartalways \ -v /var/r…...
【SpringBoot篇】详解Bean的管理(获取bean,bean的作用域,第三方bean)
文章目录 🍔Bean的获取🎄注入IOC容器对象⭐代码实现🛸根据bean的名称获取🛸根据bean的类型获取🛸根据bean的名称和类型获取 🎄Bean的作用域⭐代码实现🎈注意 🎄第三方Bean⭐代码实现…...
彭涛:2023年终复盘,工作,团队,个人!
眨眼2023即将结束,2024即将开启,每年这个时候,都会简单总结下自己这一年,既是对今年的一个复盘和回顾,也是对新一年的向往和期待。 我的2023年,大概分为 「个人」,「家庭」,「团队」…...
【数据结构和算法】---二叉树(2)--堆的实现和应用
目录 一、堆的概念及结构二、堆结构的实现2.1堆向下调整算法2.2堆向上调整算法2.3删除堆顶元素2.4插入元素2.5其他函数接口 三、堆结构的应用3.1堆排序3.2Top-k问题 四、堆概念及结构相关题目 一、堆的概念及结构 如果有一个数字集合,并把它的所有元素按完全二叉树…...
【大模型实践】基于文心一言的对话模型设计
文心一言(英文名:ERNIE Bot)是百度全新一代知识增强大语言模型,文心大模型家族的新成员,能够与人对话互动、回答问题、协助创作,高效便捷地帮助人们获取信息、知识和灵感。文心一言从数万亿数据和数千亿知识…...
聊聊PowerJob的StoreStrategy
序 本文主要研究一下PowerJob的StoreStrategy StoreStrategy tech/powerjob/worker/common/constants/StoreStrategy.java Getter AllArgsConstructor public enum StoreStrategy {DISK("磁盘"),MEMORY("内存");private final String des; }StoreStra…...
HTML+CSS+JS网页设计期末课程大作业 web课程设计 web前端开发 网页规划与设计
HTMLCSSJS网页设计期末课程大作业 web前端开发技术 web课程设计 网页规划与设计 💥 文章目录一、🚩 网站描述二、🎌 网站介绍三、🏴 网站类型A 个人博客主题B 人物明星主题C 旅游主题D 游戏主题E 动漫主题F 美食主题G 校园主题H 企…...
vscode | python | remote-SSH | Debug 配置 + CLIP4Clip实验记录
安装Extension 本地安装Remote-SSH、python 远程服务器上安装Python 难点:主机和远程服务器上安装Python扩展失败,可能是网络、代理等原因导致解决方法: 主机在官方网站下载Python扩展:https://marketplace.visualstudio.com/it…...
【Linux】实现windows主机与ubuntu虚拟机系统之间文件/字符复制粘贴
环境 硬件:通用PC 系统:Ubuntu 18.04 《 》Windows10 软件 :VMware Workstation 16 Pro 解决 0、现象 使用Ubuntu 虚拟机时,有时需要来回复制文件或者字符串到主机或虚拟机。 1、分析 2、思路 3、解决 //先安装open-vm-to…...
Ubuntu22.04-安装后Terminal无法调出
参考: Ubuntu20.04 终端打开不了的问题排查_ubuntu终端打不开-CSDN博客 https://blog.csdn.net/u010092716/article/details/130968032 Ubuntu修改locale从而修改语言环境_ubuntu locale-CSDN博客 https://blog.csdn.net/aa1209551258/article/details/81745394 问…...
ffmpeg两种windows版本区别说明
版本一 必须拷贝exe和dll文件才能使用,如果缺少dll则exe不正正常执行 如果缺少dll ,执行 exe会报错如下 版本2 直接拷贝exe就能使用,没有依赖的环境...
最新国内AI绘画Midjourney绘画提示词Prompt分享
一、Midjourney绘画工具 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭…...
ChatGPT4.0(中文版)国内无限制免费版(附网址)
ChatGPT,由OpenAI开发的人工智能语言模型。它是你的数字对话伙伴,无论你有何问题或需要什么帮助,它都能提供有用的信息。 经过不断的研发和更新,ChatGPT的性能和功能得到了显著提升。现在,我们将重点介绍ChatGPT的两个…...
模拟电路基础知识笔记,你想知道的都有,建议收藏!
大家总说模电知识总是学不会,IC修真院为大家整理了模拟电子基础知识,看看你掌握了多少,文末可以获取全部哦。 文末可领全部文档 1、PN结是晶体二极管的基本结构,也是一般半导体器件的核心。 2、 射极输出器没有电压放大能力&am…...
【强化学习】基于蒙特卡洛MC与时序差分TD的简易21点游戏应用
1. 本文将强化学习方法(MC、Sarsa、Q learning)应用于“S21点的简单纸牌游戏”。 类似于Sutton和Barto的21点游戏示例,但请注意,纸牌游戏的规则是不同且非标准的。 2. 为方便描述,过程使用代码截图,文末附链…...
Pandas 高级教程——高级时间序列分析
Python Pandas 高级教程:高级时间序列分析 Pandas 提供了强大的时间序列处理功能,使得对时间序列数据进行高级分析变得更加灵活和方便。在本篇博客中,我们将深入介绍 Pandas 中的高级时间序列分析技术,并通过实例演示如何应用这些…...
解决Pycharm pip安装模块太慢问题,pycharm2022没有manage repositories配置镜像源
解决方案 方法清华阿里云中国科技大学华中理工大学 或者直接-i 加镜像 方法 URL写下面任意一个 清华 https://pypi.tuna.tsinghua.edu.cn/simple阿里云 http://mirrors.aliyun.com/pypi/simple/中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/华中理工大学 http:/…...
十二:爬虫-Scrapy框架(上)
一:Scrapy介绍 1.Scrapy是什么? Scrapy 是用 Python 实现的一个为了爬取网站数据、提取结构性数据而编写的应用框架(异步爬虫框架) 通常我们可以很简单的通过 Scrapy 框架实现一个爬虫,抓取指定网站的内容或图片 Scrapy使用了Twisted异步网…...
BUUCTF Reverse/[2019红帽杯]Snake
BUUCTF Reverse/[2019红帽杯]Snake 下载解压缩后得到可执行文件,而且有一个unity的应用程序,应该是用unity编写的游戏 打开是一个贪吃蛇游戏 用.NET Reflector打开Assembly-CSharp.dll。(unity在打包后,会将所有的代码打进一个Ass…...
用MATLAB手把手复现CT图像重构:从原理到代码,避开R-L滤波器的Gibb‘s现象
MATLAB实战:CT图像重构中的滤波反投影与Gibbs现象规避指南 在医学影像处理领域,CT图像重构算法的实现质量直接影响诊断准确性。本文将带您深入滤波反投影法的核心原理,通过MATLAB代码实现全流程,并重点解决R-L滤波器导致的Gibbs现…...
StofDoctrineExtensionsBundle的IpTraceable扩展:自动记录用户IP地址的简单实现指南 [特殊字符]
StofDoctrineExtensionsBundle的IpTraceable扩展:自动记录用户IP地址的简单实现指南 🚀 【免费下载链接】StofDoctrineExtensionsBundle Integration bundle for DoctrineExtensions by l3pp4rd in Symfony 项目地址: https://gitcode.com/gh_mirrors/…...
SITS2026正式发布倒计时72小时:这4类AI研发团队已紧急升级知识治理体系,你还在用Wiki+钉钉硬扛?
更多请点击: https://intelliparadigm.com 第一章:AI研发知识管理:SITS2026专题 核心挑战与范式演进 AI研发正从单点模型训练转向全生命周期知识协同——SITS2026(Semantic Intelligence & Traceable Systems 2026…...
前端工程化:依赖管理最佳实践
前端工程化:依赖管理最佳实践 前言 依赖管理是前端工程化的基础!如果你的项目依赖管理混乱,那你的项目就像一个堆满杂物的仓库,难以维护。今天我就来给大家讲讲前端依赖管理的最佳实践。 为什么需要依赖管理 版本控制:…...
别再死记硬背了!手把手带你用Vivado SDK调试ZYNQ FSBL源码(附常见启动失败排查)
深入实战:用Vivado SDK调试ZYNQ FSBL源码的完整指南 在嵌入式系统开发中,理解启动流程是掌握整个系统运行机制的关键。对于Xilinx ZYNQ平台而言,First Stage Boot Loader(FSBL)作为系统启动的第一环,其重要…...
TrollInstallerX终极指南:3分钟搞定iOS 14-16.6.1 TrollStore安装
TrollInstallerX终极指南:3分钟搞定iOS 14-16.6.1 TrollStore安装 【免费下载链接】TrollInstallerX A TrollStore installer for iOS 14.0 - 16.6.1 项目地址: https://gitcode.com/gh_mirrors/tr/TrollInstallerX TrollInstallerX是当前iOS 14.0至16.6.1设…...
从CEO到营销技术专家:创业者退休后的身份重构与价值延续
1. 从创业者到“退休者”:身份的骤然转变卖掉自己一手创办并经营了近四十年的公司,这种感觉,远非“退休”二字可以概括。它不是一次计划已久的悠闲旅行,更像是一场毫无预兆的急刹车。前一天,你还在会议室里为下一代产品…...
OpenCV Aruco码检测全流程拆解:不只是二维码,更是计算机视觉的“标尺”
OpenCV ArUco码检测全流程拆解:从原理到工程优化的视觉标尺实践 在计算机视觉领域,标记检测一直是连接虚拟信息与现实世界的重要桥梁。当我们谈论ArUco码时,很多人首先联想到的是其作为二维码近亲的身份,但它的真正价值远不止于此…...
Cursor AI 编码规则启动器:模块化配置与工程化实践指南
1. 项目概述:一个为 Cursor 编辑器量身定制的规则启动器如果你和我一样,日常重度依赖 Cursor 这款 AI 驱动的代码编辑器,那你一定对它的“规则”(Rules)功能又爱又恨。爱的是,它能通过预设的指令集…...
Kubernetes部署Dify AI平台:从Docker Compose到K8s原生YAML完整迁移指南
1. 项目概述与核心价值最近在折腾AI应用开发平台,发现Dify这个工具确实挺有意思,它把大模型应用开发的门槛降得很低。不过,官方主要提供了Docker Compose的部署方式,对于已经将生产环境全面容器化、并且用上了Kubernetes的团队来说…...
