一起学SF框架系列7.1-spring-AOP-基础知识

AOP(Aspect-oriented Programming-面向切面编程)是一种编程模式,是对OOP(Object-oriented Programming-面向对象编程)一种有益补充。在OOP中,万事万物都是独立的对象,对象相互耦合关系是基于业务进行的;但在实际应用系统中,存在对大量对象的公共管理要求(如功能安全检查、日志记录、方法执行时间统计等),这些行为同业本身无关,因此是对象本身难于处理的,这就是AOP诞生和发展的原因。

基本概念

AOP要达到的目标就是在某些方法执行前或后,需要完成一种或几种通用的行为逻辑。示意图如下:
在这里插入图片描述

图中红色边框的图标组成了完整的AOP(只示意了在方法前,也可以在方法后):
日志记录:就是AOP要达成的目标-当执行对应方法时进行日志记录。对应AOP中的切面(Aspect)。
红线:代表切面(日志记录)切入位置。对应AOP概念的连接点(Joinpoint)
蓝色方块:代表切面(日志记录)真正起作用的条件。对应AOP概念的切入点(Pointcut)
红色箭头:代表发起执行的通知。对应AOP概念的通知(Advice)

术语

Aspect(切面):代指需要处理的共性业务,一个切面就是一个共性业务,如功能安全性验证就是一个切面,日志记录时另一个切面。实现时,通常处理该业务的类就代表一个切面。(中文中“切面”比“方面”更准确和形象,意思就是切入到方法前后干点事情)
Joinpoint(连接点):程序执行过程中需要切面起作用的位置,通常是对象的方法。
Advice(通知):一个切面在一个特定的连接点上采取的行动。可以更直白理解为在程序执行到连接点时,按照通知类型执行切面的对应方法。通知有五中类型(见后文)。
Pointcut(切入点):定义匹配连接点的表达式。Advice与切入点表达式相关联,并在切入点匹配的任何连接点运行(例如,执行具有特定名称的方法)。切入点表达式匹配的连接点概念是AOP的核心,Spring默认使用AspectJ切入点表达式语言。
Introduction(引言):代表类型声明其他方法或字段。Spring AOP允许您向任何通知的对象引入新的接口(以及相应的实现)。例如,您可以使用引言来使bean实现IsModified接口,以简化缓存。
Target Object(目标对象):由一个或多个切面通知的对象,即应用中同切面通知相关的业务逻辑对象。
Proxy Object(代理对象):是使用切面逻辑对业务逻辑进行包裹之后生成的对象。
AOP proxy(AOP代理):AOP框架创建的一个对象,用于实现切面的契约(如通知方法执行等)。在Spring Framework中,AOP代理是JDK动态代理或CGLIB代理。
Weaving(织入):将切面与应用程序类型或对象链接以创建通知对象。通常是框架在编译时、加载时或运行时完成。Spring AOP是在运行时执行织入。

注:目标对象和代理对象的区别
目标对象是我们声明的业务逻辑对象,而代理对象是使用切面逻辑对业务逻辑进行包裹之后生成的对象。如果使用的是Jdk动态代理,那么业务对象和代理对象将是两个对象,在调用代理对象逻辑时,其切面逻辑中会调用目标对象的逻辑;如果使用的是Cglib代理,由于是使用的子类进行切面逻辑织入的,那么只有一个对象,即织入了代理逻辑的业务类的子类对象,此时是不会生成业务类的对象的。

通知类型

Before advice:在连接点执行之前运行的通知,不能阻止执行流继续进行到连接点(除非抛出异常)。
After returning advice:在连接点正常执行完成后运行的通知(例如,如果一个方法返回而没有抛出异常)。
After throwing advice:如果方法通过抛出异常退出,则要运行的通知。
After(finally)advice:无论连接点以何种方式退出都要运行的通知(正常或异常返回)。
Around advice:围绕连接点(如方法调用)的通知。Around advice在方法执行前后都要运行对应的通知。它还负责选择是继续到连接点,还是通过返回自己的返回值或抛出异常来缩短通知方法的执行。

通知执行顺序

同一个Joinpoint如果出现多个通知,执行顺序: Around 的前advice–>Before advice–>(AfterThrowing advice)–>AfterReturn advice–>After advice–>Around的后 advice。
注意:如果发生AfterThrowing advice,后续的After Advice会执行,其它Advice则不再执行

AOP应用场景

  1. 日志记录:记录方法的入参、出参以及方法的执行时间等信息;
  2. 安全检查:在方法执行前对用户进行身份验证,判断其是否具备访问方法的权限;
  3. 性能监控:记录方法的调用频度、执行时间,方便分析程序性能瓶颈;
  4. 事务管理:在方法执行前开启事务,在方法执行后根据方法执行结果提交或回滚事务;
  5. 缓存:在方法执行前判断缓存中是否存在方法的结果,在方法执行后将结果存入缓存中,方便下次调用时使用
  6. 返回参数格式统一:可对前后端参数进行统一
  7. 异常处理:对异常可进行统一管理。

AOP实现机制

AOP是通过代理机制来实现的。

什么是代理

  ”代理“的本质是A要完成一些事,B可以代理A去完成,两者做的效果就是结果达成是一样的,但过程可能不一样。比如我要注册一家公司,肯定需获得营业执照,如果自己办理就容易跌坑,效率很低;我可以委托中介(代理)帮我完成,他们办证的过程和自己去办的过程肯定有不同,但最终目的都拿到了营业执照。从技术上来说,达成结果相同意味着直接执行方法本身即可,过程不同就意味着在方法执行之前或之后可以做其它事情。代理机制示意图如下:
在这里插入图片描述
图中可以看出代理前和代理后的区别就是方法被代理器做了封装(框架自动进行的):
1、从编码人员的角度看,两者没有任何区别,都是直接调用方法。
2、从机器角度看(编译后执行),调用实际由代理器来完成的,代理器还做了自己的事情(否则就没必要加代理器)。
3、从结果看,1和2获得的结果是一样的。

  在Java中,引入动态代理的原因如下:
  1、动态代理主要用来做方法的增强,让你可以在不修改源码的情况下,增强一些方法,在方法执行前后做任何你想做的事情(甚至根本不去执行这个方法),如添加调用日志,做事务控制等。典型的应用就是AOP。
  2、应用解耦:通过动态代理,应用之间的关系变得松散,从而更好的实现解耦合。例如,如果两个系统通过RMI通信,则每个系统都必须使用相同的消息结构和规范。动态代理允许不同的消息结构和规范之间进行映射,从而完成两个系统之间的通信。
  3、优化性能:在调用远程服务或者本地数据库时,需要建立连接或者事务。使用动态代理可以避免在每个请求上进行开销巨大的连接和事务管理操作。例如,ORM框架就是利用了动态代理,将Java对象映射到数据库表中。

技术机制

  代理类和被代理类实现共同的接口(或继承),代理类中存有指向被代理类的索引,实际执行时通过调用代理类的方法、实际执行的是被代理类的方法。

实现模式

  代理常见的实现模式有两种:静态代理和动态代理。
  静态代理,是编译时增强,框架会在编译阶段生成代理类,在程序运行前代理类的.class文件就已经存在了。常见的实现:JDK静态代理,AspectJ 。
  动态代理,是运行时增强,它不修改代理类的字节码,而是在程序运行时,运用反射机制,在内存中临时为方法生成一个代理对象,这个代理对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。常见的实现:JDK、CGLIB、Javassist(Hibernate中的使用动态代理)

CGLIB

  GLIB主要就是为了增强动态代理功能提出的开源项目。技术上就是通过动态的生成一个子类去覆盖所要代理的类(非final修饰的类和方法)。
  CGLIB主要用于AOP、 测试、数据访问等框架。
  CGLIB底层使用了ASM(一个短小精悍的字节码操作框架)来操作字节码生成新的类。
  CGLIB作为一个开源项目,其代码托管在github:https://github.com/cglib/cglib。

JDK代理和CGLIB区别

1、JDK代理只能够对接口进行代理,不能对普通的类进行代理(因为所有生成的代理类的父类为Proxy,Java类继承机制不允许多重继承);CGLIB能够代理普通类,但被代理类不能是final类或有final方法。
2、JDK代理使用Java原生的反射API进行操作,生成类比较高效;CGLIB使用ASM框架直接对字节码进行操作,类执行过程比较高效。
3、JDK代理需要自己写代理类,代理类需要实现与目标对象相同的接口。CGLIB不需要自己编写代理类,代理类是动态生成的。

Spring AOP代理

SpringAOP默认使用标准JDK动态代理作为AOP代理。这使得任何接口(或一组接口)都可以被代理。Spring AOP也可以使用CGLIB代理,如果业务对象未实现接口,则使用CGLIB。

Spring AOP功能和目标

1、Spring AOP是用纯Java实现的。Spring AOP不需要控制类加载器层次结构,因此适合在servlet容器或应用程序服务器中使用。
2、Spring AOP目前只支持方法执行连接点(建议在Spring Bean上执行方法)。虽然可以添加对字段拦截的支持,但没有实现字段拦截。如果有需要,考虑使用AspectJ。
3、Spring AOP的AOP方法不同于大多数其他AOP框架。其目的不是提供最完整的AOP实现(尽管Spring AOP非常强大)。相反,其目的是在AOP实现和SpringIoC之间提供紧密的集成,以帮助解决企业应用程序中的常见问题。因此,Spring Framework的AOP功能通常与Spring IoC容器一起使用。特点是通过使用普通的bean定义语法来配置的,这是与其他AOP实现的一个关键区别。您无法使用SpringAOP轻松或高效地完成某些事情,例如通知非常细粒度的对象(通常是域对象)。在这种情况下,AspectJ是最好的选择。
4、Spring AOP目的不是与AspectJ竞争以提供全面的AOP解决方案。它们是互补的,而不是竞争的。Spring AOP和IoC可以与AspectJ无缝集成,以在一致的基于Spring的应用程序架构中实现AOP的所有使用。

补充说明
1、Spring框架的核心原则之一是非侵入性。就是不强迫您在业务或域模型中引入特定于框架的类和接口的想法。然而,在某些地方,Spring Framework确实为您提供了将特定于Spring Framework的依赖项引入代码库的选项。提供这些选项的理由是,在某些情况下,以这种方式阅读或编码某些特定的功能可能会更容易。无论如何,Spring Framework总是为您提供选择:您可以自由地做出明智的决定,决定哪个选项最适合您的特定用例或场景。因此,您可以选择用哪种AOP框架:AspectJ、SpringAOP,或者两者兼而有之。您还可以选择@AspectJ注释样式方法或SpringXML配置样式方法。
2、应用如何选择用Spring AOP还是AspectJ?选择原则:使用最简单的可行方法。SpringAOP比使用完整的AspectJ更简单,因为不需要在开发和构建过程中引入AspectJcompiler/weaver。如果您只需要在Spring管理的bean上执行操作,那么SpringAOP是正确的选择。如果您需要通知不是由Spring容器管理的对象(通常是域对象),则需要使用AspectJ。如果希望建议连接点而不是简单方法执行(例如,字段get或设置连接点等),则还需要使用AspectJ。

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

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

相关文章

MySQL之深入InnoDB存储引擎——Undo页

文章目录 一、UNDO日志格式1、INSERT操作对应的UNDO日志2、DELETE操作对应的undo日志3、UPDATE操作对应的undo日志1)不更新主键2)更新主键的操作 3、增删改操作对二级索引的影响 二、UNDO页三、UNDO页面链表四、undo日志具体写入过程五、回滚段1、回滚段…

C语言系列之原码、反码和补码

一.欢迎来到我的酒馆 讨论c语言中,原码、反码、补码。 目录 一.欢迎来到我的酒馆二.原码 二.原码 2.1在计算机中,所有数据都是以二进制存储的,但不是直接存储二进制数,而是存储二进制的补码。原码很好理解,就是对应的…

SQL Server数据库如何添加Oracle链接服务器(Windows系统)

SQL Server数据库如何添加Oracle链接服务器 一、在添加访问Oracle的组件1.1 下载Oracle的组件 Oracle Provider for OLE DB1.2 注册该组件1.2.1 下载的压缩包解压位置1.2.2 接着用管理员运行Cmd 此处一定要用管理员运行,否则会报错 二、配置环境变量三、 重启SQL Se…

IDEA开启并配置services窗口

一、选择view -> Tool Windows -> Services 二、底下栏会出现Services 然后右键添加工程即可

Apache DolphinScheduler 3.1.8 版本发布,修复 SeaTunnel 相关 Bug

近日,Apache DolphinScheduler 发布了 3.1.8 版本。此版本主要基于 3.1.7 版本进行了 bug 修复,共计修复 16 个 bug, 1 个 doc, 2 个 chore。 其中修复了以下几个较为重要的问题: 修复在构建 SeaTunnel 任务节点的参数时错误的判断条件修复 …

【学习笔记】Java安全之反序列化

文章目录 反序列化方法的对比PHP的反序列化Java的反序列化Python反序列化 URLDNS链利用链分析触发DNS请求 CommonCollections1利用链利用TransformedMap构造POC利用LazyMap构造POCCommonsCollections6 利用链 最近在学习Phith0n师傅的知识星球的Java安全漫谈系列,随…

【多音音频测试信号】具有指定采样率和样本数的多音信号,生成多音信号的相位降低波峰因数研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【torch.nn.PixelShuffle】和 【torch.nn.UnpixelShuffle】

文章目录 torch.nn.PixelShuffle直观解释官方文档 torch.nn.PixelUnshuffle直观解释官方文档 torch.nn.PixelShuffle 直观解释 PixelShuffle是一种上采样方法,它将形状为 ( ∗ , C r 2 , H , W ) (∗, C\times r^2, H, W) (∗,Cr2,H,W)的张量重新排列转换为形状为…

TechTool Pro for mac(硬件监测和系统维护工具)

TechTool Pro 是为 Mac OS X 重新设计的全新工具程序,不但保留旧版原有的硬件侦测功能,还可检查系统上其他重要功能,如:网络连接,区域网络等。 TechTool Pro for mac随时监控和保护您的电脑,并可预设定期检…

机器学习深度学习——非NVIDIA显卡怎么做深度学习(坑点排查)

👨‍🎓作者简介:一位即将上大四,正专攻机器学习的保研er 🌌上期文章:机器学习&&深度学习——数值稳定性和模型化参数(详细数学推导) 📚订阅专栏:机器…

mac安装vscode 配置git

1、安装vscode 官网地址 下载mac稳定版安装很慢的解决办法 (转自) mac电脑如何解决下载vscode慢的问题 选择谷歌浏览器右上角的3个点,选择下载内容,右键选择复制链接地址,在新窗口粘贴地址, 把地址中的一段替换成下面的cscode.sd…

电脑文件丢失如何找回?使用这个方法轻松找回!

电脑文件丢失怎么办?有没有免费的电脑文件恢复软件?相信很多人在日常办公中也都经常会遇到这种现象,不管是在学习中,还是日常的办公,往往也都会在电脑上存储大量的数据文件,那么如果我们在日常办公操作过程…

LabVIEW开发分段反射器测试台

LabVIEW开发分段反射器测试台 随着对太空的观察需求越来越远,而不是当前技术(如哈勃望远镜)所能达到的,有必要增加太空望远镜主镜的尺寸。但是,增加主镜像的大小时存在几个问题。随着反射镜尺寸的增加,制造…

利用hfish反控境外攻击源主机

导师给了7个网络安全课题选题,本想和他聊了下思路,他一挥手让我先做出点东西再来聊就把我打发走了…… 正好前段时间阿里云到校做推广,用优惠卷薅了一台云服务器,装了hfish先看下情况 没想到才装上没两天数据库就爆了&#xff0…

构建之法 - 软工教学:每天都向前推进一点点

作者:福州⼤学 汪璟玢⽼师 汪老师:每次都向前推进一点点,哪怕只有一点点,也好过什么都不做。 ​邹老师:对,几个学期下来,就已经超过那些“空想”的团队很远了。坚持下去! 汪老师&…

wonderful-sql 作业

Sql 作业 作业1: 答: create table Employee (Id integer not null, Name varchar(32) , Salary integer, departmentId integer, primary key (Id) );create table Department( Id integer primary key, Name varchar(30) not null );insert into emp…

多雷达探测论文阅读笔记:雷达学报 2023, 多雷达协同探测技术研究进展:认知跟踪与资源调度算法

多雷达协同探测技术 原始笔记链接:https://mp.weixin.qq.com/s?__biz=Mzg4MjgxMjgyMg==&mid=2247486627&idx=1&sn=f32c31bfea98b85f2105254a4e64d210&chksm=cf51be5af826374c706f3c9dcd5392e0ed2a5fb31ab20924b7dd38e1b1ae32abe9a48afa8174#rd ↑ \uparrow …

侯捷C++高级编程(下)

对于1个类要么像指针要么像函数 主题1:转换函数 转换函数 /** 1. 转换函数没有返回类型* 2. 转换函数一般需要加上const*/ class Fraction { public:Fraction(int num,int den1):m(num),n(den){cout<<"Fraction(int num,int den1): m/n "<< m/n<&…

WebGL: 几个入门小例子

本文通过WebGL例子&#xff0c;来帮助WebGL入门学习。 一、概述 WebGL (Web Graphics Library)是一组基于Open ES、在Web内渲染3D图形的Javascript APIs。 Ref. from Khronos Group: WebGL WebGL™ is a cross-platform, royalty-free open web standard for a low-level 3D …

web前端之JS

文章目录 介绍一、JS引入到文件1.1 嵌入到HTML文件中1.2 引入本地独立JS文件1.3 引入网络来源文件 二、JS的注释三、JS输出方式四、JS数据类型4.1 判断数据类型 typeof4.2 charAt返回指定位置的字符4.3 concat连接两个字符串4.4 substring从原字符串提取字符串并返回4.4 substr…