Spring原理揭秘--Spring的AOP

在这之前我们已经介绍了AOP的基本功能和概念,那么当AOP集成到spring则会发生改变。

Spring AOP 中的Joinpoint:

之前提高了很多Joinpoint的类型,但是在spring中则只会有方法级别的Joinpoint,像构造方法,字段的调用都没适配。原因是Spring框架一直追求轻量级和高效,而仅仅采用方法级的Joinpoint即可满足百分之八十的需求。同时如果采用类中的属性级别的Joinpoint则会破坏对象的封装。如果需求非常特殊超过了拿百分之八十的需求那么不妨可以使用AspectJ的方式。

Spring AOP 中的Pointcut:

Spring中以接口定义Pointcut作为其最顶层的抽象接口,该接口定义了两个方法用来帮助捕获系统中相应的Joinpoint

两个方法的ClassFilter和MethodMatcher分别是用来匹配将执行织入操作的对象以及相应的方法。

也就是说ClassFilter是对于类型对象的匹配而MethodMatcher则是对于方法级别的匹配,

MethodMatcher的复杂度相比于ClassFilter要高。原因是ClassFilter仅仅只需要匹配类型即可而MethodMatcher则可能需要匹配方法名称或者方法名称+参数

因此对于MethodMatcher则有多个方法进行匹配

有两个matches的方法,而这两个方法的分界线就是isRuntime方法。在对具体的方法进行拦截的时候,可以忽略每次方法执行的时候调用者传入的参数,也可以每次都检查这些方法调用参数,以强化拦截条件,都是与isRuntime的返回值有关如果返回值为false则会触发第一个matches方法这种属于不会考虑具体方法的参数,而如果返回结果为true则会调用第二个matches方法表示采用参数的匹配

将这两个MethodMatcher类型分为StaticMethodMatcher和DynamicMethodMatcher类型。StaticMethodMatcher类型则是无参数检查,这种无需参数检查的类型可以缓存在框架内部,同时性能比较出色,对于DynamicMethodMatcher类型是参数检查,因此不会进行缓存操作,同时性能上相比StaticMethodMatcher则是损耗很大。

常见的PointCut

下面我们来介绍几个常见的PointCut

NameMatchMethodPointcut:

这个是最简单的Pointcut实现,属于StaticMethodMatcher的子类,可以根据自身指定的一组方法名称与Joinpoint处的方法的名称进行匹配

JdkRegexpMethodPointcut和Perl5RegexpMethodPointcut

StaticMethodMatcher的子类有一个专门基于正则表达式的实现分支,而JdkRegexpMethodPointcut和Perl5RegexpMethodPointcut则是不同类型的正则表达式的具体实现。

AnnotationMatchingPointcut

根据目标对象中是否存在指定类型的注解来匹配Joinpoint,要使用该类型的Pointcut首先需要声明相应的注解。

CompossablePointcut

提供逻辑运算功能,而ComposablePointcut就是Spring AOP提供的可以进行Pointcut逻辑运算的Pointcut实现。它可以实现Pointcut之间的并以及交运算。

ControlFlowPointcut

ControlFlowPointcut则是最特殊的Pointcut类型,在理解和使用上都需要我们多付出点脑细胞,ControlFlowPointcut匹配程序的调用流程,不是对某个方法执行所在的Joinpoint处的单一特征进行匹配。通过ControlFlowPointcut我们可以实现指定只有当某个类的方法在被执行的类对象调用的时候才会对方法进行拦截处理

Spring AOP中的Advice

Advice实现了将被织入到Pointcut规定的Joinpoint处的横切逻辑。在spring中,advice按照其自身实例能否在目标对象类的所有实例中共享这一标准,可以划分为两大类,即per-class类型的advice和per-instance类型的advice。

per-class类型的Advice

per-class类型的Advice是指该类型的实例可以在目标对象类的所有实例之间进行共享,这种类型的Advice只是提供方法拦截的功能,不会为目标对象类保存任何状态或者添加新的特性。

那么per-class有着以下几种类型

Before advice

实现的横切逻辑将在相应的Joinpoint之前执行,在Before advice执行完成之后,程序执行流程将从Joinpoint处继续执行,所以Before Advice通常不会打断程序执行的流程,但是如果有必要,也可以通过抛出相应异常的形式中断程序流程

ThrowsAdvice

throwsAdvice通常用于对系统重特定的异常情况的监控,以统一的方式对所发生的异常进行处理,一旦捕获到异常,需要马上以某种方式通知系统的监控或者运营人员

AfterReturningAdvice

通过spring的AfterReturningAdvice,我们可以访问当前joinpoint的方法返回值,方法,方法参数以及所在的目标对象

Around Advice

Spring AOP没有提供AfterAdvice,使得我们没有一个合适的advice类型来承载类似于系统资源清除之类的横切逻辑。Spring AOP的AfterReturningAdvice不能更改Joinpoint所在方法的返回值,使得我们在方法正常返回后无法对其进行更多的敢于。有了Around Advice则可以解决这个问题

per-instance类型的Advice

在Spring AOP当中只有一个类型的per-instance型Advice就是Introduction

Introduction

Introduction允许你在不修改目标类代码的情况下,为其动态添加新的接口和实现。这相当于在运行时为目标对象 “混入” 额外的行为,使其具备原本没有的功能。

// 定义新接口
public interface Monitorable {void setMonitorActive(boolean active);boolean isMonitorActive();
}// 实现接口和 IntroductionInterceptor
public class MonitorInterceptor implements MethodInterceptor, Monitorable {private boolean monitorActive = false;@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {if (monitorActive && invocation.getMethod().getName().startsWith("get")) {System.out.println("Monitoring: " + invocation.getMethod().getName());}return invocation.proceed();}@Overridepublic void setMonitorActive(boolean active) {this.monitorActive = active;}@Overridepublic boolean isMonitorActive() {return monitorActive;}
}// 创建 IntroductionAdvisor
public class MonitorAdvisor extends DefaultIntroductionAdvisor {public MonitorAdvisor() {super(new MonitorInterceptor(), Monitorable.class);}
}
增强类型作用是否改变类结构
Before/After在方法前后添加行为
Around环绕方法执行,完全控制调用过程
Introduction为目标对象添加新接口和实现是(运行时)

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

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

相关文章

C++学习笔记五

C继承//基类 class Animal{};//派生类 class Dog : public Animal{};#include<iostearm> using namespace std;//基类 class Shape{public:void setwidth(int w){width w;}void setheight(int h){height h;}protected:int width;int height;}//派生类 class Rectangle …

AndroidStudio环境搭建

一、AndroidStudio下载 正常百度出来的站会自动翻译成中文&#xff0c;导致历史版本的界面总是显示不出可下载的地方&#xff0c;点击成切回英文&#xff0c;就能看出了。 历史版本&#xff1a;https://developer.android.google.cn/studio/archive

Java大厂面试实录:从Spring Boot到AI大模型的深度技术拷问

场景&#xff1a;互联网大厂Java后端面试 面试官&#xff08;严肃&#xff09;&#xff1a;小曾&#xff0c;请坐。今天主要考察Java后端技术栈&#xff0c;包括微服务、大数据、AI等。我们先从简单问题开始。 小曾&#xff08;搓手&#xff09;&#xff1a;好嘞&#xff01;面…

深入解析Hadoop中的HDFS架构设计

HDFS概述与核心设计原则作为Hadoop生态系统的基石&#xff0c;HDFS&#xff08;Hadoop Distributed File System&#xff09;是一种专为大规模数据处理而设计的分布式文件系统。它的核心设计理念源于对互联网时代数据特征的深刻洞察——数据规模呈指数级增长&#xff0c;而硬件…

ota之.加密算法,mcu加密方式

一、ota之.加密算法&#xff0c;mcu加密方式 前面一篇文章&#xff0c;讲了soc的加密方式&#xff0c;但是soc资源充足&#xff0c;mcu没有&#xff0c;所以不会用openss生成公私钥 切计算哈希用rsa256位。 ECC&#xff08;椭圆曲线加密&#xff09; 是一种非对称加密算法&…

LangChain面试内容整理-知识点23:实战案例:检索增强生成(RAG)系统

检索增强生成(Retrieval-Augmented Generation, RAG)是一种将LLM与外部知识库结合的方法,通过实时检索相关信息来辅助生成答案。这极大缓解了LLM“封闭知识”过期或不足的问题。LangChain非常适合构建RAG系统,因为它提供了文档加载、向量存储、检索接口、LLM组合的一站式方…

探索阿里云ESA:开启边缘安全加速新时代

阿里云 ESA 是什么&#xff1f;阿里云 ESA&#xff0c;全称边缘安全加速&#xff08;Edge Security Acceleration&#xff09; &#xff0c;其前身为全站加速 DCDN&#xff08;Dynamic Content Delivery Network&#xff09;。在 2024 年 9 月 30 日&#xff0c;阿里云完成了这…

醋酸铈:赋能科技创新的稀土之力

一、什么是醋酸铈醋酸铈是铈元素与醋酸根离子形成的化合物。铈作为稀土元素中的重要一员&#xff0c;广泛应用于材料科学、催化剂、电子产品等领域。醋酸铈以无色结晶或浅黄色结晶的形式存在&#xff0c;是铈的有机盐之一。它不仅具有稳定的化学性质&#xff0c;而且在某些特定…

数据结构之普利姆算法

前言&#xff1a;Prim算法是图论中的算法&#xff0c;用来生成图的最小生成树。本篇文章介绍算法的流程&#xff0c;实现思想&#xff0c;和具体代码实现&#xff0c;使用c语言。学习需要输出才能理解的更透彻&#xff0c;所以说坚持写文章&#xff0c;希望可以用自己的方式把一…

构建强大的物联网架构所需了解的一切

数据正驱动着当今的商业发展&#xff0c;而物联网&#xff08;IoT&#xff09;则有助于为企业的增长和创新开辟新的机遇。麦肯锡的研究表明&#xff0c;全球数据在四年内实现了惊人的 7 倍增长。随着越来越多的物联网设备进入市场&#xff0c;更多企业开始需要强大的物联网架构…

java之json转excel生成

背景 业务为实现自定义样式excel的导出&#xff0c;常规的做法就是根据数据在代码中进行类似模版的配置&#xff1b;这样的体验不是很好&#xff0c;只要用户改变下样式的设置不用代码改动就能实现自定义excel的导出更加灵活。 以下是具体实现 pom依赖 <dependency><g…

新版本Cursor中配置自定义MCP服务器教程,附MCP工具开发实战源码

在 Cursor 中配置自定义 MCP 服务器&#xff1a;打造你的 AI 开发工具链 引言 随着 AI 编程助手的普及&#xff0c;开发者们越来越希望能够定制化自己的开发环境。Cursor 作为一款强大的 AI 编程编辑器&#xff0c;提供了 Model Context Protocol (MCP) 支持&#xff0c;新版本…

前端面试十二之vue3基础

一、ref和reactive在 Vue 3 中&#xff0c;ref 和 reactive 是两种主要的响应式数据创建方式&#xff0c;它们各有特点和适用场景。1.refref 主要用于创建单个值的响应式引用&#xff0c;通常用于基本类型数据&#xff0c;如数字、字符串等。使用 ref 创建的引用对象可以通过 .…

设计模式四:装饰模式(Decorator Pattern)

装饰模式是一种结构型设计模式&#xff0c;它允许你动态地给一个对象添加额外的职责&#xff0c;相比继承更加灵活。1. 模式定义装饰模式&#xff1a;动态地给一个对象添加一些额外的职责。就增加功能来说&#xff0c;装饰模式相比生成子类更为灵活。2. 模式结构主要角色&#…

神经网络常见激活函数 14-Mish函数

文章目录Mish函数导函数函数和导函数图像优缺点PyTorch 中的 Mish 函数TensorFlow 中的 Mish 函数Mish 论文 https://arxiv.org/pdf/1908.08681 函数导函数 Mish函数 Mish(x)x⋅tanh⁡⁣(softplus(x))x⋅tanh⁡⁣(ln⁡⁣(1ex))\begin{aligned} \text{Mish}(x) & x \cdot \t…

LAMP迁移LNMP Nginx多站点配置全流程

文章目录前言备份与停止服务nginx安装与配置nginx 编译安装配置服务php-fpm多站点配置phf-fpm介绍多站点配置nginx 多站点配置nginx ssl 配置参考前言 之前服务器使用的是 LAMP环境&#xff0c;想充分利用服务器资源&#xff0c;再运行另外一个站点 在LAMP环境下应该是也可以…

Nginx屏蔽国外IP访问

下载IP列表 # 下载到文件 wget http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest # 直接输出到终端 curl -sSL https://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest得到一份国内IP配置 # 原始IP列表格式&#xff1a;apnic|CN|ipv4|218.78.0.0|1310…

stl-string模拟

1.介绍主要进行cpp中string的模拟&#xff0c;方便我们更好的对stl进行使用&#xff0c;string没有模板&#xff0c;我们将头文件和函数写在两个不同的文件2.头文件3.cpp文件如有问题&#xff0c;欢迎纠正&#xff01;

基于MATLAB的极限学习机ELM的数据回归预测方法应用

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取 或者私信获取。 1.项目背景 在当今的数据驱动时代&#xff0c;准确且高效的预测模型对于解决复杂问题至关重要。极限学习机&#…

芯谷科技--双四通道模拟/数字多路复用器74HC4052

在电子系统中&#xff0c;信号的多路复用与解复用是常见的需求&#xff0c;特别是在需要对多个信号源进行选择和切换的场景中。芯谷科技推出的 74HC4052 双四通道模拟/数字多路复用器/解复用器&#xff0c;以其高效、灵活的设计&#xff0c;为工程师提供了可靠的解决方案。产品…