东莞易宣网站建设公司怎么样/长春网络推广公司哪个好

东莞易宣网站建设公司怎么样,长春网络推广公司哪个好,网络推广是干嘛的可以做吗,中国知名的建网站的公司前言 本文首先介绍了责任链的基本原理,并附带一个例子说明责任链模式,确保能够理解责任链的前提下,在进行Spring AOP执行责任链的源码分析。责任链模式允许将多个处理对象连接成链,请求沿着链传递,直到被处理或结束。每…

前言

  本文首先介绍了责任链的基本原理,并附带一个例子说明责任链模式,确保能够理解责任链的前提下,在进行Spring AOP执行责任链的源码分析。责任链模式允许将多个处理对象连接成链,请求沿着链传递,直到被处理或结束。每个处理者可以选择处理请求或传递给下一个。

  Spring AOP的拦截器链,拦截器或者过滤器链,都是典型的责任链应用。比如,当一个方法被调用时,多个拦截器按顺序执行,每个拦截器可以决定是否继续执行链中的下一个。

  深入Spring AOP的源码部分,特别是拦截器链的执行过程。比如,在Spring AOP中,当调用一个被增强的方法时,会创建一个MethodInvocation对象,其中包含拦截器链。每个拦截器都是一个Advice,比如MethodInterceptor。这时候,责任链模式的应用可能体现在拦截器的依次调用上,每个拦截器处理完后调用下一个,直到最后一个拦截器执行实际的方法。

  具体分析Spring的源码,比如ReflectiveMethodInvocation类的proceed方法。这个方法可能负责按顺序调用拦截器链中的每个拦截器,直到所有拦截器处理完毕,最后调用目标方法。这个流程是否符合责任链模式的结构?是的,每个拦截器处理请求,并决定是否传递下去。

  可能还需要比较责任链模式的不同变体,比如纯的责任链(每个处理者必须处理请求)和不纯的(可以传递)。Spring AOP的拦截器链属于后者,每个拦截器都可以选择是否继续传递,或者在处理前后执行某些操作,然后继续传递。

  另外,Spring AOP的基本原理不在本文中介绍了,详情请看以往文章,有更加详细的表述,有理论和源码的解析。文章:Spring AOP源码解析

  实际应用场景本文也涉及到,如何自定义拦截器,如何调整拦截器链的顺序,或者如何利用责任链模式实现类似的功能。这些实际应用案例可以增强回答的实用性。

  最后,确保回答结构清晰,先解释责任链模式,再结合Spring源码详细说明,最后总结其优势和应用场景。需要避免过于冗长的代码分析,而是突出重点部分,比如关键类和方法的调用流程。


责任链模式原理详解与源码实例


一、责任链模式(Chain of Responsibility Pattern)原理

核心思想:将多个处理对象连成一条链,请求沿链传递,直到有一个处理对象处理它或链结束。每个处理对象可选择处理请求或传递给下一个对象。

1. 模式结构
角色职责
Handler(抽象处理者)定义处理请求的接口,通常包含指向下一个处理者的引用(nextHandler)。
ConcreteHandler具体处理者,实现处理逻辑,或决定是否将请求传递到下一个处理者。
Request请求对象,封装请求的上下文数据。
2. 类图
+----------------+          +-------------------+
|   Handler      | <|-------| ConcreteHandlerA  |
+----------------+          +-------------------+
| +nextHandler   |          | +handleRequest()  |
| +handleRequest()|         +-------------------+
+----------------+                   ^|                            ||                            |
+-------------------+
| ConcreteHandlerB  |
+-------------------+
| +handleRequest()  |
+-------------------+
3. 执行流程
  1. 客户端将请求发送到责任链的第一个处理者。
  2. 每个处理者决定是否处理该请求:
    • 若处理,则终止传递。
    • 若不处理,则调用 nextHandler.handleRequest()
  3. 请求沿链传递,直到被处理或链结束。

二、责任链模式源码实例
1. 抽象处理者(Handler)
public abstract class Handler {protected Handler nextHandler; // 指向下一个处理者public void setNextHandler(Handler nextHandler) {this.nextHandler = nextHandler;}public abstract void handleRequest(Request request);
}
2. 具体处理者(ConcreteHandler)
public class ConcreteHandlerA extends Handler {@Overridepublic void handleRequest(Request request) {if (canHandle(request)) {System.out.println("ConcreteHandlerA 处理请求: " + request.getData());} else if (nextHandler != null) {nextHandler.handleRequest(request); // 传递给下一个处理者}}private boolean canHandle(Request request) {return request.getType().equals("A");}
}public class ConcreteHandlerB extends Handler {@Overridepublic void handleRequest(Request request) {if (canHandle(request)) {System.out.println("ConcreteHandlerB 处理请求: " + request.getData());} else if (nextHandler != null) {nextHandler.handleRequest(request); // 传递给下一个处理者}}private boolean canHandle(Request request) {return request.getType().equals("B");}
}
3. 请求对象(Request)
public class Request {private String type; // 请求类型private String data; // 请求数据public Request(String type, String data) {this.type = type;this.data = data;}public String getType() { return type; }public String getData() { return data; }
}
4. 客户端调用
public class Client {public static void main(String[] args) {// 创建责任链Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();handlerA.setNextHandler(handlerB);// 发送请求Request request1 = new Request("A", "请求1");Request request2 = new Request("B", "请求2");handlerA.handleRequest(request1); // 由 ConcreteHandlerA 处理handlerA.handleRequest(request2); // 由 ConcreteHandlerB 处理}
}

输出结果

ConcreteHandlerA 处理请求: 请求1
ConcreteHandlerB 处理请求: 请求2

三、Spring AOP 拦截器链中的责任链模式

Spring AOP 通过 拦截器链(Interceptor Chain) 实现方法增强(如事务、日志),其核心设计正是基于责任链模式。

1. 核心组件
组件职责
MethodInvocation封装被代理方法的调用上下文(类似 Request)。
MethodInterceptor拦截器接口(类似 Handler),定义增强逻辑。
ReflectiveMethodInvocation具体责任链实现,管理拦截器链的调用顺序。
2. 源码解析
(1)拦截器链的创建

在生成代理对象时,Spring 会将所有匹配的拦截器(如 MethodInterceptor)按顺序组合成链。

入口AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {// 获取所有拦截器(包括事务、日志等)List<Object> interceptorList = new ArrayList<>();for (Advisor advisor : this.advisors) {if (advisor instanceof PointcutAdvisor) {// 匹配拦截器是否适用于当前方法if (((PointcutAdvisor) advisor).getPointcut().getMethodMatcher().matches(method, targetClass)) {interceptorList.add(advisor.getAdvice());}}}return interceptorList;
}
(2)责任链的触发

代理对象调用方法时,触发 ReflectiveMethodInvocation#proceed(),按顺序执行拦截器链。该方法类似于递归执行,递归方法也是有终止条件的,请注意区分。

源码ReflectiveMethodInvocation

public class ReflectiveMethodInvocation implements ProxyMethodInvocation {private final Object target;          // 目标对象private final Method method;          // 目标方法private final Object[] arguments;     // 方法参数private final List<Object> interceptorsAndDynamicMethodMatchers; // 拦截器链private int currentInterceptorIndex = -1; // 当前拦截器索引public Object proceed() throws Throwable {// 1. 所有拦截器执行完毕,调用原始方法if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}// 2. 获取下一个拦截器Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);// 3. 执行拦截器逻辑if (interceptorOrInterceptionAdvice instanceof MethodInterceptor) {MethodInterceptor mi = (MethodInterceptor) interceptorOrInterceptionAdvice;return mi.invoke(this); // 将当前 MethodInvocation 传递给拦截器} else {// 动态匹配器处理(略)}}// 调用原始方法protected Object invokeJoinpoint() throws Throwable {return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);}
}
(3)拦截器的执行逻辑

每个 MethodInterceptor 拦截器决定是否继续传递链(调用 proceed())或终止。

示例:Spring 事务拦截器 TransactionInterceptor

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor {public Object invoke(MethodInvocation invocation) throws Throwable {// 1. 开启事务TransactionInfo txInfo = createTransactionIfNecessary(invocation.getMethod(), targetClass);try {// 2. 继续执行拦截器链(责任链传递)Object retVal = invocation.proceed();// 3. 提交事务commitTransactionAfterReturning(txInfo);return retVal;} catch (Throwable ex) {// 4. 回滚事务completeTransactionAfterThrowing(txInfo, ex);throw ex;}}
}

四、责任链模式在 Spring AOP 中的设计优势
  1. 灵活扩展
    新增拦截器只需实现 MethodInterceptor 并注册到链中,无需修改现有代码。

  2. 逻辑解耦
    每个拦截器专注单一职责(如事务、日志),通过链式调用组合功能。

  3. 动态控制流程
    拦截器可决定是否继续调用链(如权限校验失败时直接抛出异常终止流程)。

  4. 执行顺序可控
    拦截器链的顺序可通过 @Order 注解或实现 Ordered 接口调整。


五、实际应用场景与自定义拦截器
1. 自定义拦截器示例
public class LoggingInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println("方法调用前: " + invocation.getMethod().getName());Object result = invocation.proceed(); // 继续链System.out.println("方法调用后: " + invocation.getMethod().getName());return result;}
}
2. 配置拦截器链

在 Spring 配置中注册拦截器:

<bean id="loggingInterceptor" class="com.example.LoggingInterceptor"/>
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"/><aop:config><aop:advisor advice-ref="loggingInterceptor" order="1"/><aop:advisor advice-ref="transactionInterceptor" order="2"/>
</aop:config>
3. 执行顺序

拦截器按 order 值从小到大依次执行:

LoggingInterceptor(前置日志) → TransactionInterceptor(事务管理) → 目标方法

六、总结
  • 责任链模式核心:解耦请求发送者与处理者,允许多个对象按链式处理请求。
  • Spring AOP 实现:通过 ReflectiveMethodInvocation 管理拦截器链,每个 MethodInterceptor 按责任链模式依次执行。
  • 优势:灵活扩展、职责分离、动态流程控制。
  • 应用场景:事务管理、日志记录、权限校验、性能监控等切面功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/895983.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React 与 Vue 对比指南 - 上

React 与 Vue 对比指南 - 上 本文将展示如何在 React 和 Vue 中实现常见功能&#xff0c;从基础渲染到高级状态管理 Hello 分别使用 react 和 vue 写一个 Hello World&#xff01; react export default () > {return <div>Hello World!</div>; }vue <…

大模型开发实战篇7:语音识别-语音转文字

语音识别大模型&#xff0c;是人工智能领域的一项重要技术&#xff0c;它能够将人类的语音转换为文本。近年来&#xff0c;随着深度学习技术的不断发展&#xff0c;语音识别大模型取得了显著的进展&#xff0c;并在各个领域得到了广泛应用。 主流语音识别大模型 目前&#xf…

解锁机器学习核心算法 | K -近邻算法:机器学习的神奇钥匙

一、引言 今天我们继续学习机器学习核心算法 —— K - 近邻&#xff08;K-Nearest Neighbors&#xff0c;简称 KNN&#xff09;算法。它就像是一位经验丰富的 “老江湖”&#xff0c;以其简单而又强大的方式&#xff0c;在众多机器学习任务中占据着不可或缺的地位。 K - 近邻…

【DeepSeek】本地部署,保姆级教程

deepseek网站链接传送门&#xff1a;DeepSeek 在这里主要介绍DeepSeek的两种部署方法&#xff0c;一种是调用API&#xff0c;一种是本地部署。 一、API调用 1.进入网址Cherry Studio - 全能的AI助手选择立即下载 2.安装时位置建议放在其他盘&#xff0c;不要放c盘 3.进入软件后…

Python 入门教程(2)搭建环境 | 2.3、VSCode配置Python开发环境

文章目录 一、VSCode配置Python开发环境1、软件安装2、安装Python插件3、配置Python环境4、包管理5、调试程序 前言 Visual Studio Code&#xff08;简称VSCode&#xff09;以其强大的功能和灵活的扩展性&#xff0c;成为了许多开发者的首选。本文将详细介绍如何在VSCode中配置…

【第二节】C++设计模式(创建型模式)-抽象工厂模式

目录 引言 一、抽象工厂模式概述 二、抽象工厂模式的应用 三、抽象工厂模式的适用场景 四、抽象工厂模式的优缺点 五、总结 引言 抽象工厂设计模式是一种创建型设计模式&#xff0c;旨在解决一系列相互依赖对象的创建问题。它与工厂方法模式密切相关&#xff0c;但在应用…

ubuntu20.04重启后不显示共享文件夹

ubuntu20.04重启后不显示共享文件夹 主要参见这两篇博客 Ubuntu重启后不显示共享文件夹_ubuntu 20.04 共享目录无法使用-CSDN博客 ubuntu22.04 配置共享文件夹 找不到/mnt/hgfs_ubuntu安装tools 后mnt文件夹在哪-CSDN博客 重启Ubuntu20.04后&#xff0c;发现共享文件夹进不去…

halcon机器视觉深度学习对象检测,物体检测

目录 效果图操作步骤软件版本halcon参考代码本地函数 get_distinct_colors()本地函数 make_neighboring_colors_distinguishable() 效果图 操作步骤 首先要在Deep Learning Tool工具里面把图片打上标注文本&#xff0c; 然后训练模型&#xff0c;导出模型文件 这个是模型 mod…

2.19学习(php文件后缀)

misc buu-后门查杀 下载附件&#xff0c;我们用火绒安全扫一下然后点击详情进入该文件所在文件夹&#xff0c;再用记事本打开该文件&#xff0c;搜索flag无果&#xff0c;再试试pass&#xff08;由题目中的密码联系到pass&#xff0c;password&#xff0c;key等&#xff09;&a…

PMBOK第7版整体架构全面详解

1. 引言 7月1日对于项目管理从业者和研究者而言&#xff0c;是个非凡意义的一个时间&#xff0c;这一天&#xff0c;翘首以待的《 项 目管理知识体系指南 》&#xff08;PMBOK&#xff09;第七版终于发布了。 总体而言&#xff0c;PMBOK第七版集百家之所长&#xff0c;成一…

C++:类与对象,定义类和构造函数

#define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> using namespace std; //如何让定义一个类 // 封装 // 1、将数据和方法定义到一起。 // 2、把想给你看的数据给你看&#xff0c;不想给你看的封装起来。 通过访问限定符来实现 class Stack { public: //1.成…

nginx 部署前端vue项目

?? 主页&#xff1a; ?? 感谢各位大佬 点赞?? 收藏 留言?? 加关注! ?? 收录于专栏&#xff1a;前端工程师 文章目录 一、??什么是nginx&#xff1f;二、??nginx 部署前端vue项目步骤 2.1 ??安装nginx 2.1.1 ??windows环境安装2.1.2 ??linux环境安装 2.2 …

蓝桥杯备考策略

备赛策略 (1-2周):基础算法数据结构 (3-5周):动态规划/贪心图论 (6-8周):全真模拟查漏补缺 阶段1:基础巩固(第1-2周) **目标:**掌握基础数据结构和必考算法&#xff0c;熟悉蓝桥杯题型。 学习内容: 数据结构:数组、字符串、栈、队列、哈希表、二叉树(遍历与基本操作)。 基础…

tmux和vim的基本操作

Tmux Tmux 的核心功能 多窗口和多面板&#xff1a; 在一个终端中创建多个窗口&#xff08;Windows&#xff09;&#xff0c;每个窗口可以运行不同的任务。 在每个窗口中&#xff0c;可以进一步分割成多个面板&#xff08;Panes&#xff09;&#xff0c;实现分屏操作。 会话…

HTTP SSE 实现

参考&#xff1a; SSE协议 SSE技术详解&#xff1a;使用 HTTP 做服务端数据推送应用的技术 一句概扩 SSE可理解为&#xff1a;服务端和客户端建立连接之后双方均保持连接&#xff0c;但仅支持服务端向客户端推送数据。推送完毕之后关闭连接&#xff0c;无状态行。 下面是基于…

推荐一款AI大模型托管平台-OpenWebUI

推荐一款AI大模型托管平台-OpenWebUI 1. OpenWebUI 1. OpenWebUI什么? 官网地址&#xff1a;https://openwebui.com/ GitHub地址&#xff1a; https://github.com/open-webui/open-webui Open WebUI 是一个可扩展、功能丰富且用户友好的自托管 AI 平台&#xff0c;旨在完全离…

java练习(33)

ps:题目来自力扣 最强回文子串 给你一个字符串 s&#xff0c;找到 s 中最长的 回文 子串。 class Solution {public String longestPalindrome(String s) {if (s null || s.length() < 1) {return "";}int start 0, end 0;for (int i 0; i < s.length();…

本地部署DeepSeek大模型

环境&#xff1a;nuc工控机器 x86架构 ubuntu20.04 1、浏览器打开Download Ollama on Linux&#xff0c;复制命令。 2.打开终端&#xff0c;输入命令。 curl -fsSL https://ollama.com/install.sh | sh 等待安装&#xff0c;安装完成后&#xff0c;终端输入 ollama&#xff…

【Spring详解一】Spring整体架构和环境搭建

一、Spring整体架构和环境搭建 1.1 Spring的整体架构 Spring框架是一个分层架构&#xff0c;包含一系列功能要素&#xff0c;被分为大约20个模块 Spring核心容器&#xff1a;包含Core、Bean、Context、Expression Language模块 Core &#xff1a;其他组件的基本核心&#xff…

用openresty和lua实现壁纸投票功能

背景 之前做了一个随机壁纸接口&#xff0c;但是不知道大家喜欢对壁纸的喜好&#xff0c;所以干脆在实现一个投票功能&#xff0c;让用户给自己喜欢的壁纸进行投票。 原理说明 1.当访问http://demo.com/vote/时&#xff0c;会从/home/jobs/webs/imgs及子目录下获取图片列表&…