【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

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

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

相关文章

Kafka

消息中间件的作用 异步解耦削峰填谷 MQ对比 RabbitMQ 优点&#xff1a;管理界面最好用&#xff1b;支持语言较多&#xff1b; 缺点&#xff1a;不支持扩展&#xff08;集群&#xff09; 主要流程&#xff1a;生产者发送消息给交换机&#xff0c;通过路由机制投递到对应的队…

Python入门【​编辑、组合、设计模式_工厂模式实现 、设计模式_单例模式实现、工厂和单例模式结合、异常是什么?异常的解决思路 】(十七)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列专栏&#xff1a;python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 &#x1f4e7;如果文章知识点有错误…

构造方法 与代理

构造方法 public class Son {String name;/*构造方法1.与类名相同2.没有返回值也没有void*//*作用&#xff1a;实例化初始值使用new关键字必须要有构造器*/public Son(){//无参构造方法this.name"sss";}//有参构造方法public Son(String name){//定义有参构造 就必…

【云存储】使用OSS快速搭建个人网盘教程(阿里云)

使用OSS快速搭建个人网盘 一、基础概要1. 主要的存储类型1.1 块存储1.2 文件存储1.3 对象存储 2. 对象存储OSS2.1 存储空间2.2 地域2.3 对象2.4 读写权限2.5 访问域名&#xff08;Endpoint&#xff09;2.6 访问密钥2.7 常用功能&#xff08;1&#xff09;创建存储空间&#xff…

WebGL Shader着色器GLSL语言

在2D绘图中的坐标系统&#xff0c;默认情况下是与窗口坐标系统相同&#xff0c;它以canvas的左上角为坐标原点&#xff0c;沿X轴向右为正值&#xff0c;沿Y轴向下为正值。其中canvas坐标的单位都是’px’。 WebGL使用的是正交右手坐标系&#xff0c;且每个方向都有可使用的值的…

MFC第二十六天 CRgn类简介与开发、封装CMemoryDC类并应用开发

文章目录 CRgn类简介与开发CRgn类简介CRgn类区域管理开发CRgn类区域管理与不规则形状的选取 封装CMemoryDC类并应用开发CMemoryDC.h封装CMemoryDC开发游戏透明动画CFlashDlg.hCFlashDlg.cpp 封装CMemoryDC开发游戏动画 附录四大窗口CDC派生类 CRgn类简介与开发 CRgn类简介 CR…

c高级:day3

作业: 1. 整理思维导图 2.判断家目录下,普通文件的个数和目录文件的个数 #!/bin/bash ######################################################################## # File Name: zy1.sh # Created Time: 2023年08月04日 星期五 19时13分08秒 ##############################…

计算机网络(2) --- 网络套接字UDP

计算机网络&#xff08;1&#xff09; --- 网络介绍_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/131967378?spm1001.2014.3001.5501 目录 1.端口号 2.TCP与UDP协议 1.TCP协议介绍 1.TCP协议 2.UDP协议 3.理解 2.网络字节序 发送逻辑…

html,css日常记录

动态绑定class&#xff0c;当index3!0时&#xff0c;class的值为bdt :class"{bdt:index3!0}" 动态绑定style中的height和lineheight&#xff0c;其中&#xff0c;height的值为函数px(item.length)的返回值&#xff0c;函数名可以随意取。 :style"{height:px(…

SpringBoot使用@Autowired将实现类注入到List或者Map集合中

前言 最近看到RuoYi-Vue-Plus翻译功能 Translation的翻译模块配置类TranslationConfig&#xff0c;其中有一个注入TranslationInterface翻译接口实现类的写法让我感到很新颖&#xff0c;但这种写法在Spring 3.0版本以后就已经支持注入List和Map&#xff0c;平时都没有注意到这…

基于 Redux + TypeScript 实现强类型检查和对 Json 的数据清理

基于 Redux TypeScript 实现强类型检查和对 Json 的数据清理 突然像是打通了任督二脉一样就用了 generics 搞定了之前一直用 any 实现的类型…… 关于 Redux 的部分&#xff0c;这里不多赘述&#xff0c;基本的实现都在这里&#xff1a;Redux Toolkit 调用 API 的四种方式 和…

机器学习概述及其主要算法

目录 1、什么是机器学习 2、数据集 2.1、结构 3、算法分类 4、算法简介 4.1、K-近邻算法 4.2、贝叶斯分类 4.3、决策树和随机森林 4.4、逻辑回归 4.5、神经网络 4.6、线性回归 4.7、岭回归 4.8、K-means 5、机器学习开发流程 6、学习框架 1、什么是机器学习 机器…

Emacs之set-face-attribute与font-lock-add-keywords用法区别(一百二十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

在java中如何使用openOffice进行格式转换,word,excel,ppt,pdf互相转换

1.首先需要下载并安装openOffice,下载地址为&#xff1a; Apache OpenOffice download | SourceForge.net 2.安装后&#xff0c;可以测试下是否可用&#xff1b; 3.build.gradle中引入依赖&#xff1a; implementation group: com.artofsolving, name: jodconverter, version:…

笔记:Android 9系统启动流程

启动流程 1.按下电源&#xff0c;系统启动 当电源键按下时&#xff0c;引导芯片代码&#xff08;汇编指令&#xff09;会从预定的地方&#xff08;固化在ROM&#xff09;开始执行&#xff0c;将引导程序 BootLoader 加载到 RAM中&#xff0c;然后执行 2.引导程序 BootLoader …

【3维视觉】3D空间常用算法(点到直线距离、面法线、二面角)

3D空间点到直线的距离 3D空间点到直线的距离 3D空间的曲率 三维空间有三个基本元素&#xff0c;点&#xff0c;线&#xff0c;面。那么曲率是如何定义的呢&#xff1f; 点的曲率&#xff1f; 线的曲率&#xff1f; 面的曲率&#xff1f; 法曲率 设曲面上的曲线在某一点处的切…

Unity 使用SharpZipLib解压时报错

报错信息&#xff1a; NotSupportedException: Encoding 936 data could not be found. Make sure you have correct international System.Text.Encoding.GetEncoding (System.Int32 codepage) ICSharpCode.SharpZipLib.Zip.ZipConstants.ConvertToString。 出现问题分析&…

【SpringBoot】日志是+基于lombok的日志输出

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE进阶 在我们日常的程序开发中&#xff0c;日志是程序的重要组成部分&#xff0c;想象⼀下&#xff0c;如果程序报错了&#xff0c;不让你打开控制台看⽇志&#xff0c;那么你能找到报错的原因吗…

leetcode37. 解数独(java)

解数独 解数独题目描述回溯算法代码演示 回溯算法 解数独 难度 困难 leetcode37. 解数独 题目描述 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 1.数字 1-9 在每一行只能出现一次。 2.数字 1-9 在每一列只能出现一次。 3.数字…

【C++】开源:ncurses终端TUI文本界面库

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍ncurses终端文本界面库。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下…