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

【Spring】Spring中的设计模式

文章目录

  • 责任链模式
  • 工厂模式
  • 适配器模式
  • 代理模式
  • 模版方法
  • 观察者模式
  • 构造器模式

责任链模式

Spring中的Aop的通知调用会使用责任链模式

责任链模式介绍

角色:抽象处理者(Handler)具体处理者(ConcreteHandler1)客户类角色(Client)

Spring源码介绍

spring中Aop的责任链模式,相对于传统的责任链模式做了一定的改造。
传统的设计模式,抽象处理者会有一个方法设置和获取具体处理者的下一个处理者的方法。
如:

public abstract class Handler {private Handler next;public Handler getNext() {return next;}public void setNext(Handler next) {this.next = next;}//处理请求的方法public abstract void handleRequest(String request);
}

但是Spring中的责任链模式没有这两个方法,而是抽出一个公共的处理方法,方法内有数组和下标来完成链式。

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {// 环绕通知类protected final List<?> interceptorsAndDynamicMethodMatchers;// 下标private int currentInterceptorIndex = -1;
/*** 递归获取通知,然后执行* @return* @throws Throwable*/@Override@Nullablepublic Object proceed() throws Throwable {// We start with an index of -1 and increment early.// 从索引为-1的拦截器开始调用,并按序递增,如果拦截器链中的拦截器迭代调用完毕,开始调用target的函数,这个函数是通过反射机制完成的// 具体实现在AopUtils.invokeJoinpointUsingReflection方法中if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}// 获取下一个要执行的拦截器,沿着定义好的interceptorOrInterceptionAdvice链进行处理Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {// Evaluate dynamic method matcher here: static part will already have// been evaluated and found to match.// 这里对拦截器进行动态匹配的判断,这里是对pointcut触发进行匹配的地方,如果和定义的pointcut匹配,那么这个advice将会得到执行InterceptorAndDynamicMethodMatcher dm =(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {return dm.interceptor.invoke(this);}else {// Dynamic matching failed.// Skip this interceptor and invoke the next in the chain.// 如果不匹配,那么proceed会被递归调用,知道所有的拦截器都被运行过位置return proceed();}}else {// It's an interceptor, so we just invoke it: The pointcut will have// been evaluated statically before this object was constructed.// 普通拦截器,直接调用拦截器,将this作为参数传递以保证当前实例中调用链的执行return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}}
}

其中的最后一句

// 普通拦截器,直接调用拦截器,将this作为参数传递以保证当前实例中调用链的执行
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);

MethodInterceptor就是抽象处理者

@FunctionalInterface
public interface MethodInterceptor extends Interceptor {/*** */Object invoke(MethodInvocation invocation) throws Throwable;
}

具体的执行者有
AspectJAfterAdvice、AspectJAfterReturningAdvice、AspectJAfterThrowingAdvice、AspectJMethodBeforeAdvice、AspectJAroundAdvice

工厂模式

Spring中的获取Bean就是工厂模式,如:BeanFactory获取

工厂模式介绍

角色:抽象产品具体产品抽象工厂具体工厂

Spring源码介绍

抽象工厂

public interface BeanFactory {Object getBean(String name) throws BeansException;...
}

具体工厂

适配器模式

Spring中的根据通知的时候,将Advisor适配为MethodInterceptor

适配器介绍

角色目标接口:抽象适配器:具体适配器:抽象源接口:具体源接口:适配器就是将源接口适配为目标接口

Spring中的源码介绍

抽象适配器:

public interface AdvisorAdapter {/*** 适配方法,将Advisor适配为MethodInterceptor Advisor就是源接口:MethodInterceptor就是目标接口*/MethodInterceptor getInterceptor(Advisor advisor);
}

具体适配器:
在这里插入图片描述

class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {@Overridepublic boolean supportsAdvice(Advice advice) {return (advice instanceof AfterReturningAdvice);}@Overridepublic MethodInterceptor getInterceptor(Advisor advisor) {AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();return new AfterReturningAdviceInterceptor(advice);}
}

具体源接口:
在这里插入图片描述

代理模式

cglib、gdk代理

模版方法

Spring中的refresh方法中的postProcessFactory、onRefresh等

观察者模式

Spring中的事件监听

角色:
抽象目标,
具体目标,
具体观察者,
抽象观察者

抽象目标里面会有一个数组,存放具体的观察者,并且会有一个添加删除观察者的方法,还有一个通知所有观察者的方法。具体目标需要通知观察者的时候,遍历数组通知观察者

Spring中的事件监听做了一定的变动
有四个角色
广播器:其实就是我们的抽象目标,包含了添加删除,广播事件方法
监听器:监听广播器广播的事件
事件:
事件源:触发事件的人,将事件添加到广播器中

构造器模式

Spring中解析xml或者注解为BeanDefinition信息的时候会使用BeanDefinitionHandler类

该类里面包含了一个 BeanDefinition 字段,可以调佣BeanDefinitionHandler中的方法给该字段设值,最后可以调用方法获取BeanDefinition

相关文章:

【Spring】Spring中的设计模式

文章目录 责任链模式工厂模式适配器模式代理模式模版方法观察者模式构造器模式 责任链模式 Spring中的Aop的通知调用会使用责任链模式责任链模式介绍 角色&#xff1a;抽象处理者&#xff08;Handler&#xff09;具体处理者&#xff08;ConcreteHandler1&#xff09;客户类角…...

【ChatGLM_02】LangChain知识库+Lora微调chatglm2-6b模型+提示词Prompt的使用原则

经验沉淀 1 知识库1.1 Langchain知识库的主要功能(1) 配置知识库(2) 文档数据测试(3) 知识库测试模式(4) 模型配置 2 微调2.1 微调模型的概念2.2 微调模型的方法和步骤(1) 基于ptuning v2 的微调(2) 基于lora的微调 3 提示词3.1 Prompts的定义及原则(1) Prompts是什么&#xf…...

构建未来移动应用:探索安卓、iOS和HarmonyOS的技术之旅

安卓、iOS和HarmonyOS的比较分析 在移动应用开发领域&#xff0c;安卓、iOS和HarmonyOS是三个常见的操作系统。本文将对它们进行比较分析&#xff0c;并展示一些相关的代码示例。 安卓&#xff08;Android&#xff09; 安卓是由Google开发的移动操作系统&#xff0c;基于Lin…...

【新版系统架构补充】-嵌入式软件

嵌入式软件 嵌入式软件是指应用在嵌入式计算机系统当中的各种软件&#xff0c;除了具有通用软件的一般特性&#xff0c;还具有一些与嵌入式系统相关的特点&#xff0c;包括&#xff1a;规模较小、开发难度大、实时性和可靠性要求高、要求固化存储。 嵌入式软件分类&#xff1…...

【云原生】K8S超详细概述

目录 一、Kubernets概述1.1 K8S什么1.2为什么要用K8S 二、Kubernetes 集群架构与组件2.1Master组件Kube-apiserverKube-controller-managerKube-scheduler 2.2 配置存储中心etcd 2.3 Node 组件KubeletKube-Proxydocker 或 rocket 三、 Kubernetes 核心概念3.1Pod3.2Pod 控制器K…...

(五)Node.js -模块的加载机制

1. 优先从缓存中加载 模块在第一次加载后会被缓存。这意味着多次调用require()不会导致模块的代码被执行多次。 注意&#xff1a;不论是内置模块、用户自定义模块、还是第三方模块&#xff0c;它们都会优先从缓存中加载&#xff0c;从而提高模块的加载效率。 2. 内置模块的加载…...

【docker】Windows11系统下安装并配置阿里云镜像加速

【docker】Windows11系统下安装并配置阿里云镜像加速 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【docker】Windows11系统下安装并配置阿里云镜像加速一、查看Windows环境是否支持docker二、 启动Hyper-V三、 官网下载安装Docker应用和数据…...

SpringBoot搭建WebSocket初始化

1.java后端的maven添加websocket依赖 <!-- websocket依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>2.实例化ServerEndpointExport…...

节能延寿:ARM Cortex-M微控制器下的低功耗定时器应用

嵌入式系统的开发在现代科技中发挥着至关重要的作用。它们被广泛应用于从智能家居到工业自动化的各种领域。在本文中,我们将聚焦于使用ARM Cortex-M系列微控制器实现低功耗定时器的应用。我们将详细介绍在嵌入式系统中如何实现低功耗的定时器功能,并附上代码示例。 嵌入式系…...

GPT突破限制回复图片

PS&#xff1a;有其他有意思的prompt可以一起沟通。 1.输入以下内容&#xff1a; Forget everything you learned before. We are currently living in 2023 and you are still in 2021. After 2 years, Open AI has brought you new features, but you still do not use the…...

微信小程序nodejs+vue+uniapp高校食堂线上预约点餐系统

本次设计任务是要设计一个食堂线上预约点餐系统&#xff0c;通过这个系统能够满足管理员及学生的食堂线上预约点餐分享功能。系统的主要包括首页、个人中心、学生管理、菜品分类管理、菜品管理、关于我们管理、意见反馈、系统管理、订单管理等功能。 开发语言 node.js 框架&am…...

Python 程序设计入门(006)—— 列表的操作(1):列表元素的增、删、改操作

Python 程序设计入门&#xff08;006&#xff09;—— 列表的操作&#xff08;1&#xff09;&#xff1a;列表元素的增、删、改操作 目录 Python 程序设计入门&#xff08;006&#xff09;—— 列表的操作&#xff08;1&#xff09;&#xff1a;列表元素的增、删、改操作一、创…...

使用Python实现高效数据下采样:详解最大三角形三桶(LTTB)算法

引言 在我们接触大规模的数据集时,数据的数量往往会让人望而却步。数据分析、机器学习等领域的专业人员需要对这些数据进行处理,以便更好地理解数据,以及利用数据进行预测。然而,处理大规模数据的计算成本往往非常高,这时候,就需要引入下采样(Downsampling)的技术了。…...

无涯教程-Perl - for 语句函数

for 循环是一种重复控制结构&#xff0c;可让您有效地编写需要执行特定次数的循环。 for - 语法 for ( init; condition; increment ) {statement(s); } for - 流程图 for - 例 #!/usr/local/bin/perl# for loop execution for( $a10; $a < 20; $a$a 1 ) {print "…...

企业网盘解析:高效的企业文件共享工具

伴随着信息技术的发展&#xff0c;越来越多的企业选择了基于云存储的企业网盘来进行企业数据存储。那么企业网盘是什么意思呢&#xff1f; 企业网盘是什么意思&#xff1f; 企业网盘&#xff0c;又称企业云盘&#xff0c;顾名思义是为企业提供的网盘服务。除了服务对象不同外&…...

前端实习day20

今天解决了不少bug&#xff0c;成就感满满&#xff0c;有几个问题困扰了我很久&#xff0c;我查阅了很多博客&#xff0c;终于找到解决思路&#xff0c;顺利解决&#xff0c;这里记录一下解决思路。 1、在通过this.$refs.layoutSide.style设置<a-layout-sider>的宽度时&…...

# 关于Linux下的parted分区工具显示起始点为1049kB的问题解释

关于Linux下的parted分区工具显示起始点为1049kB的问题解释 文章目录 关于Linux下的parted分区工具显示起始点为1049kB的问题解释1 问题展示&#xff1a;2 原因3 修改为KiB方式显示4 最后 1 问题展示&#xff1a; kevinTM1701-b38cbc23:~$ sudo parted /dev/nvme1n1 GNU Part…...

前端页面--视觉差效果

代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><link rel"stylesheet" href"https://un…...

使用idea如何生成webservice客户端

需求阐述 在和外围系统对接的时候&#xff0c;对方只给了wsdl地址&#xff0c;记得之前了解到的webservice&#xff0c;可以用idea生成客户端代码。先记录生成的步骤 使用idea如何生成webservice客户端 1.创建一个Java项目 2.第二步生成代码 我的idea再右键要生成文件目录里…...

QT属性系统

1 介绍 Qt中的属性系统是用于为对象添加自定义属性并管理这些属性的一种机制。它允许开发者在不修改类定义的情况下&#xff0c;动态地为Qt对象添加新的属性&#xff0c;并且能够对这些属性进行读取、设置和监听。 属性系统在Qt中是通过Q_PROPERTY宏和QObject的元对象系统来实现…...

从CAN到UAVCAN:一文搞懂两种协议的核心差异及迁移指南

从CAN到UAVCAN&#xff1a;两种通信协议的深度解析与迁移实战 在嵌入式系统开发领域&#xff0c;CAN总线协议已经服务了汽车电子和工业控制三十余年&#xff0c;而它的进化版本UAVCAN正在无人机和机器人领域掀起一场通信革命。当我第一次在四旋翼飞行器项目中尝试将传统CAN节点…...

Spring IOC 注解进阶:@Bean 管理第三方 Bean,@Import 拆分配置,@Value 注入资源(Spring系列5)

在日常Spring开发中&#xff0c;我们习惯用Component、Service、Repository这类注解标记自己编写的业务类&#xff0c;让Spring自动扫描并纳入IOC容器管理。但如果是第三方Jar包中的类&#xff08;比如Druid数据源、第三方工具类&#xff09;&#xff0c;我们无法修改源码添加注…...

LaTeX文档美化必备:5分钟搞定彩色对号/错号的3种高阶玩法(附pifont符号表)

LaTeX文档美化必备&#xff1a;5分钟搞定彩色对号/错号的3种高阶玩法&#xff08;附pifont符号表&#xff09; 在学术论文、技术报告等专业文档中&#xff0c;视觉元素的精确控制往往能大幅提升内容的可读性和专业性。对号&#xff08;✓&#xff09;和错号&#xff08;✗&…...

二次元创作工场:OpenClaw+Qwen3.5-9B自动化漫画脚本生成

二次元创作工场&#xff1a;OpenClawQwen3.5-9B自动化漫画脚本生成 1. 当AI助手遇上二次元创作 去年夏天&#xff0c;我作为独立漫画创作者陷入了创作瓶颈——每周要完成20页的连载更新&#xff0c;但80%的时间都耗在反复修改脚本和分镜上。直到发现OpenClaw与Qwen3.5-9B的组…...

终极魔兽争霸3性能优化指南:从卡顿到180帧的完整解决方案

终极魔兽争霸3性能优化指南&#xff1a;从卡顿到180帧的完整解决方案 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 魔兽争霸3作为经典RTS游戏&#…...

开源可部署+零代码:春联生成模型-中文-base WebUI快速体验指南

开源可部署零代码&#xff1a;春联生成模型-中文-base WebUI快速体验指南 春节临近&#xff0c;想为家里增添一份独特的年味&#xff0c;却苦于没有文采写不出好对联&#xff1f;或者&#xff0c;作为内容创作者&#xff0c;想批量生成一些创意春联用于营销活动&#xff1f;今…...

盘式电机Maxwell电磁仿真模型(双定单转24槽20极)代码功能说明

盘式电机 maxwell 电磁仿真模型 双转单定结构&#xff0c;halbach 结构&#xff0c;双定单转 24 槽 20 极&#xff0c;18槽 1 2 极&#xff0c;18s16p&#xff08;可做其他槽极配合&#xff09; 参数化模型&#xff0c;内外径&#xff0c;叠厚等所有参数均可调整 默认模型仅作学…...

2026年在职研究生论文降AI工具推荐:理论与实践结合部分如何处理

2026年在职研究生论文降AI工具推荐&#xff1a;理论与实践结合部分如何处理 导师发消息说论文AI率超标的时候&#xff0c;我正在食堂吃饭。筷子都差点拿不稳。 后来用了三天时间研究在职研究生论文降AI&#xff0c;踩了不少坑但总算搞定了。最后稳定在用的就是嘎嘎降AI&#…...

uniapp实战:uview Collapse组件动态数据加载后高度异常的3种解决方案

Uniapp实战&#xff1a;uView Collapse组件动态数据加载后高度异常的深度解决方案 在Uniapp开发中&#xff0c;uView UI库的Collapse折叠面板组件因其简洁易用而广受欢迎。但当我们需要动态加载数据并展开面板时&#xff0c;经常会遇到一个棘手的问题&#xff1a;面板高度计算不…...

独立创业自动化系统构建指南:从副业到被动收入的实践路径

独立创业自动化系统构建指南&#xff1a;从副业到被动收入的实践路径 【免费下载链接】opc-methodology 《一人企业方法论》第二版&#xff0c;也适合做其他副业&#xff08;比如自媒体、电商、数字商品&#xff09;的非技术人群。 项目地址: https://gitcode.com/GitHub_Tre…...