Spring AOP详解-Spring官方原版

news/2024/4/27 4:44:35/文章来源:https://blog.csdn.net/leesinbad/article/details/129191750

一、概述

面向方面编程(AOP)补充了面向对象编程(OOP) 提供了另一种思考程序结构的方式。模块化的关键单元 在OOP中是类,而在AOP中,模块化的单位是方面。方面 实现跨越问题(如事务管理)的模块化 多种类型和对象。(这种关切通常被称为“跨领域”关切

Spring 的关键组件之一是 AOP 框架。虽然春季国际奥委会 容器不依赖于AOP(这意味着如果您不需要,则不需要使用AOP ),AOP补充了Spring IoC,提供了一个非常有能力的中间件解决方案。

带AspectJ切入点的弹簧AOP
Spring 提供了简单而强大的方法来编写自定义方面,方法是使用基于模式的方法或@AspectJ注释样式。 这两种风格都提供了完全键入的建议和使用AspectJ切入点语言 同时仍然使用春季AOP进行编织。
本章讨论基于架构和@AspectJ的 AOP 支持。

AOP在Spring Framework中用于:

  • 提供声明式企业服务。此类服务最重要的服务是声明式事务管理。

  • 让用户实现自定义方面,通过 AOP 补充他们对 OOP 的使用。

二、AOP 概念

让我们从定义一些核心的AOP概念和术语开始。这些术语不是 弹簧专用。不幸的是,AOP术语并不是特别直观。 但是,如果Spring使用自己的术语,那就更令人困惑了。

  • Aspect:跨多个类的关注点的模块化。事务管理是企业Java应用程序中横切关注点的一个很好的例子。在SpringAOP中,方面是通过使用正则类(基于模式的方法)或用@Aspect注释(@AspectJ样式)注释的正则类来实现的。

  • Join point:程序执行期间的点,例如执行 方法或异常的处理。在春季AOP中,连接点始终 表示方法执行。

  • Advice:某个方面在特定连接点执行的操作。不同类型的 建议包括“周围”、“之前”和“之后”通知。(建议类型讨论 后来。许多AOP框架,包括Spring,将建议建模为拦截器和 在连接点周围维护拦截器链。

  • Pointcut:与连接点匹配的谓词。建议与 切入点表达式,并在与切入点匹配的任何连接点处运行(例如, 执行具有特定名称的方法)。连接点匹配的概念 by pointcut 表达式是 AOP 的核心,Spring 使用 AspectJ 切入点 默认情况下为表达式语言。

  • Introduction:代表类型声明其他方法或字段。Spring AOP 允许您将新接口(和相应的实现)引入任何 建议对象。例如,您可以使用介绍使 Bean 实现接口IsModified,以简化缓存。(简介称为 AspectJ 社区中的类型间声明。

  • 目标对象:由一个或多个方面建议的对象。也称为 “建议对象”。由于 Spring AOP 是使用运行时代理实现的,因此这 对象始终是代理对象。

  • AOP代理:由AOP框架创建的对象,以实现方面 合约(建议方法执行等)。在 Spring 框架中,AOP 代理 是 JDK 动态代理或 CGLIB 代理。

  • 织入:将方面与其他应用程序类型或对象链接以创建 建议对象。这可以在编译时完成(使用 AspectJ 编译器,用于 示例)、加载时间或运行时。Spring AOP,像其他纯Java AOP框架一样, 在运行时执行编织。

Spring AOP 包括以下类型的通知:

  • @Before(): 切点方法执行之前执行

  • @After(): 切点方法执行之后执行

  • @Around(): 在切点方法执行前、后都可以做一些操作

  • @AfterReturning():切点方法返回结果之后执行

  • @AfterThrowing():异常通知,切点抛出异常时执行

三、SpringAOP能力和目标

Spring AOP是用纯Java实现的。无需特殊编译 过程。Spring AOP 不需要控制类加载器层次结构,因此 适用于 Servlet 容器或应用程序服务器。

Spring AOP 目前仅支持方法执行连接点(建议执行Spring beans的方法)。未实现字段拦截,尽管支持 可以在不破坏核心 Spring AOP API 的情况下添加字段拦截。如果您需要 若要建议字段访问和更新连接点,请考虑使用诸如 AspectJ 之类的语言。

Spring AOP的AOP方法与大多数其他AOP框架不同。目标是 不提供最完整的AOP实现(尽管Spring AOP相当 有能力)。相反,其目的是在AOP实现和 Spring IoC,帮助解决企业应用中的常见问题。

因此,例如,Spring 框架的 AOP 功能通常用于 与 Spring IoC 容器结合使用。使用普通 Bean 配置方面 定义语法(尽管这允许强大的“自动代理”功能)。这是一个 与其他 AOP 实现的关键区别。你不能做某些事情 使用Spring AOP轻松或有效地,例如建议非常细粒度的对象(通常, 域对象)。在这种情况下,AspectJ是最佳选择。然而,我们的 经验是,Spring AOP为大多数问题提供了出色的解决方案 适用于 AOP 的企业 Java 应用程序。

Spring AOP从未试图与AspectJ竞争以提供全面的AOP解决方案。我们认为,基于代理的框架(如SpringAOP)和成熟的框架(例如AspectJ)都是有价值的,它们是互补的,而不是竞争对手。Spring将SpringAOP和IoC与AspectJ无缝集成,以在一致的基于Spring的应用程序架构中实现AOP的所有使用。这种集成不会影响Spring AOP API或AOP Alliance API。Spring AOP保持向后兼容。

Spring 框架的核心原则之一是非侵入性。这 是不应该强迫您引入特定于框架的类的想法,并且 连接到您的业务或领域模型。但是,在某些地方,Spring 框架 确实为您提供了将特定于 Spring 框架的依赖项引入您的 代码库。为您提供此类选项的理由是因为,在某些情况下,它 可能只是更容易阅读或编码某些特定的功能,例如 一种方式。但是,Spring 框架(几乎)总是为您提供选择:您有 自由地做出明智的决定,选择哪种选项最适合您的特定用途 案例或场景。
与本章相关的一个这样的选择是哪个AOP框架(和 哪个 AOP 样式)来选择。您可以选择AspectJ,Spring AOP或两者兼而有之。你 也可以选择@AspectJ注释样式的方法或Spring XML 配置样式方法。本章选择介绍的事实 首先@AspectJ式的方法不应被视为Spring团队的标志 偏爱@AspectJ注释样式的方法,而不是Spring XML配置样式。

四、AOP 代理

Spring AOP 默认对 AOP 代理使用标准 JDK 动态代理。这 允许代理任何接口(或接口集)。

Spring AOP也可以使用CGLIB代理。这对于代理类而不是 接口。默认情况下,如果业务对象未实现 接口。由于对接口而不是类进行编程是一种很好的做法,因此业务 类通常实现一个或多个业务接口。在那些(希望很少见的)情况下,可以强制使用 CGLIB,在这种情况下 需要建议未在接口上声明的方法或需要的地方 将代理对象作为具体类型传递给方法。

重要的是要掌握Spring AOP是基于代理的事实。请参阅了解 AOP 代理以彻底检查这到底是什么 实现细节实际上意味着。

五、@AspectJ支持

@AspectJ是指将方面声明为常规 Java 类的样式,该类使用 附注。@AspectJ风格是由AspectJ项目作为AspectJ 5版本的一部分引入的。春天 使用AspectJ提供的库解释与AspectJ 5相同的注释 用于切入点解析和匹配。不过,AOP 运行时仍然是纯粹的 Spring AOP,并且 不依赖于AspectJ编译器或Weaver。

1. 启用@AspectJ支持

要在Spring配置中使用@AspectJ方面,需要启用Spring支持,以基于@AspectJ方面配置SpringAOP,并基于这些方面是否建议使用自动代理bean。通过自动代理,我们的意思是,如果Spring确定一个bean被一个或多个方面建议,它会自动为该bean生成一个代理,以拦截方法调用,并确保根据需要运行建议。

@AspectJ支持可以通过XML或Java风格的配置启用。在这两种情况下,您还需要确保AspectJ的aspectjweaver.jar库位于应用程序的类路径中(1.8或更高版本)。该库位于AspectJ发行版的lib目录中,或Maven Central存储库中。

使用 Java 配置启用@AspectJ支持

要使用Java@Configuration启用@AspectJ支持,请添加@EnableAspectJAutoProxy注释,如下例所示:

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {}

2.声明切面

启用@AspectJ支持后,Spring会自动检测在应用程序上下文中定义的任何bean,该bean的类是@AspectJaspect(具有@aspect注释),并用于配置SpringAOP。接下来的两个示例显示了一个不太有用的方面所需的最小定义。

两个示例中的第一个显示了应用程序上下文中的常规bean定义,该定义指向具有@Aspect注释的bean类:

@Aspect
public class NotVeryUsefulAspect {}

Aspect(用@Aspect注释的类)可以具有方法和字段,与任何其他类相同。它们还可以包含切入点、建议和介绍(类型间)声明。

通过组件扫描自动检测方面
您可以通过@configuration类中的@Bean方法将方面类注册为Spring XML配置中的常规Bean,或者让Spring通过类路径扫描自动检测它们 — 与任何其他Spring管理的bean相同。但是,请注意,@Aspect注释不足以在类路径中自动检测。为此,您需要添加一个单独的@Component注释(或者,根据Spring组件扫描程序的规则,添加一个符合条件的自定义原型注释)。

3. 声明切入点

Spring AOP只支持Spring bean的方法执行连接点,因此您可以将切入点视为与Spring bean上的方法执行相匹配。切入点声明有两个部分:一个由名称和任何参数组成的签名,以及一个切入点表达式,它精确地确定我们感兴趣的方法执行。在AOP的@AspectJ注释样式中,切入点签名由一个常规方法定义提供,并且通过使用@pointcut注释来指示切入点表达式(用作切入点签名的方法必须具有void返回类型)。

一个示例可以帮助明确切入点签名和切入点表达式之间的区别。以下示例定义了一个名为anyOldTransfer的切入点,该切入点与名为transfer的任何方法的执行相匹配:

@Pointcut("execution(* transfer(..))") // the pointcut expression
private void anyOldTransfer() {} // the pointcut signature

形成@pointcut注释值的切入点表达式是一个常规AspectJ切入点表达式。有关AspectJ切入点语言的完整讨论,请参阅《AspectJ编程指南》(以及AspectJ 5开发人员笔记本)或关于AspectJ的书籍之一(如Colyer等人的EclipseAspectJ,或RamnivasLadad的AspectJ in Action)。

支持的切入点

Spring AOP支持以下用于切入点表达式的AspectJ切入点指示符(PCD):

  • execution:用于匹配方法执行连接点。这是使用SpringAOP时要使用的主要切入点指示符。

  • within:将匹配限制为特定类型内的连接点(使用SpringAOP时在匹配类型内声明的方法的执行)。

  • this:将匹配限制为连接点(使用Spring AOP时方法的执行),其中bean引用(Spring AOP代理)是给定类型的实例。

  • target:将匹配限制为连接点(使用SpringAOP时方法的执行),其中目标对象(被代理的应用程序对象)是给定类型的实例。

  • args:将匹配限制为连接点(使用SpringAOP时方法的执行),其中参数是给定类型的实例。

  • @target:将匹配限制为连接点(使用SpringAOP时方法的执行),其中执行对象的类具有给定类型的注释。

  • @args:将匹配限制为连接点(使用SpringAOP时方法的执行),其中传递的实际参数的运行时类型具有给定类型的注释。

  • @within:限制匹配到具有给定注释的类型内的连接点(使用SpringAOP时,使用给定注释在类型中声明的方法的执行)。

  • @annotation:将匹配限制为连接点的主题(在Spring AOP中运行的方法)具有给定注释的连接点。

其他切入点
完整的AspectJ切入点语言支持Spring中不支持的其他切入点指示符:call、get、set、预初始化、static初始化、初始化、处理程序、adviceexecution、withincode、cflow、cflowbelow、if、@this和@withincode。在Spring AOP解释的切入点表达式中使用这些切入点指示符会导致抛出IllegalArgumentException。
SpringAOP支持的一组切入点指示符可以在未来的版本中扩展,以支持更多的AspectJ切入点指示符。

由于Spring AOP仅将匹配限制为方法执行连接点,因此前面对切入点指示符的讨论给出了比AspectJ编程指南中更窄的定义。此外,AspectJ本身具有基于类型的语义,在执行连接点,this和target都引用同一个对象:执行方法的对象。Spring AOP是一个基于代理的系统,它区分了代理对象本身(绑定到这个)和代理后面的目标对象(绑定到目标)。

组合切入点表达式

可以使用&&、|和!组合切入点表达式!。还可以按名称引用切入点表达式。以下示例显示了三个切入点表达式:

@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {} (1)@Pointcut("within(com.xyz.myapp.trading..*)")
private void inTrading() {} (2)@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {} (3)
  1. anyPublicOperation如果方法执行连接点表示执行,则匹配 任何公共方法。

  1. inTrading如果方法执行在交易模块中,则匹配。

  1. tradingOperation如果方法执行表示 交易模块。

如前所示,最好用较小的命名组件构建更复杂的切入点表达式。当按名称引用切入点时,正常的Java可见性规则适用(您可以看到相同类型的私有切入点、层次结构中的受保护切入点、任何位置的公共切入点等等)。可见性不影响切入点匹配。

共享公共切入点定义

在使用企业应用程序时,开发人员通常希望从几个方面引用应用程序的模块和特定的操作集。为此,我们建议定义一个捕获公共切入点表达式的CommonPointcuts方面。此方面通常类似于以下示例:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;@Aspect
public class CommonPointcuts {/*** A join point is in the web layer if the method is defined* in a type in the com.xyz.myapp.web package or any sub-package* under that.*/@Pointcut("within(com.xyz.myapp.web..*)")public void inWebLayer() {}/*** A join point is in the service layer if the method is defined* in a type in the com.xyz.myapp.service package or any sub-package* under that.*/@Pointcut("within(com.xyz.myapp.service..*)")public void inServiceLayer() {}/*** A join point is in the data access layer if the method is defined* in a type in the com.xyz.myapp.dao package or any sub-package* under that.*/@Pointcut("within(com.xyz.myapp.dao..*)")public void inDataAccessLayer() {}/*** A business service is the execution of any method defined on a service* interface. This definition assumes that interfaces are placed in the* "service" package, and that implementation types are in sub-packages.** If you group service interfaces by functional area (for example,* in packages com.xyz.myapp.abc.service and com.xyz.myapp.def.service) then* the pointcut expression "execution(* com.xyz.myapp..service.*.*(..))"* could be used instead.** Alternatively, you can write the expression using the 'bean'* PCD, like so "bean(*Service)". (This assumes that you have* named your Spring service beans in a consistent fashion.)*/@Pointcut("execution(* com.xyz.myapp..service.*.*(..))")public void businessService() {}/*** A data access operation is the execution of any method defined on a* dao interface. This definition assumes that interfaces are placed in the* "dao" package, and that implementation types are in sub-packages.*/@Pointcut("execution(* com.xyz.myapp.dao.*.*(..))")public void dataAccessOperation() {}}

未完待续

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

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

相关文章

【华为OD机试模拟题】用 C++ 实现 - 求解连续数列(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 分积木(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - 吃火锅(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - RSA 加密算法(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - 构成的正方形数量(2023.Q1) 【华为OD机试模拟…

【异常】导出Excel异常This archive contains unclosed entries.

一、异常说明 二、定位问题代码 一看问题, 上下文都是与订单相关的内容。 查询代码的使用地方,发现出现在这个Mybatis的select语句中 查看备注,发现是订单物流,那就没跑了, 肯定是商城的物流模块出了问题 那是什么地…

Gin获取Response Body引发的OOM

有轮子尽量用轮子 😭 😭 😭 😭 😭 😭 我们在开发中基于Gin开发了一个Api网关,但上线后发现内存会在短时间内暴涨,然后被OOM kill掉。具体内存走势如下图: 放大其中一次 在…

软件测试之测试模型

软件测试的发展 1960年代是调试时期(测试即调试) 1960年 - 1978年 论证时期(软件测试是验证软件是正确的)和 1979年 - 1982年 破坏性测试时期(为了发现错误而执行程序的过程) 1983年起,软件测…

springboot+vue.js协同过滤算法之智能旅游推荐系统java

目 录 第一章 绪论 3 1.1课题背景 3 1.2课题研究的目的和意义 3 1.3 研究现状 4 1.4论文所做的主要工作 4 第二章 技术介绍 5 2.1B/S结构 5 2.2MySQL 介绍 5 2.3MySQL环境配置 6 第三章 系统分析与设计 8 3.1系统说明 8 3.2系统可行性分析…

xray API漏洞检测

一、介绍 一款功能强大的安全评估工具。国内长亭科技研发,xray 并不开源。目前支持的漏洞检测类型包括:XSS漏洞检测 (key: xss)SQL 注入检测 (key: sqldet)命令/代码注入检测 (key: cmd-injection)目录枚举 (key: dirscan)路径穿越检测 (key: path-traversal)XML 实…

【Linux】进程间通信(无名/有名管道及System V共享内存)

目录 一、通信的相关概念 二、管道(半双工) 1、管道的概念 三、匿名管道(fork实现,用于父子及血缘关系进程间通信) 1、匿名管道的使用 2、匿名管道的读写情况 3、管道的特征 4、基于匿名管道的进程池 四、命名…

【华为OD机试模拟题】用 C++ 实现 - 密室逃生游戏(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

独家 | 6个Python数据科学库正在狂飙,你一定要学来提升文化素养

作者:Bex T翻译:wwl 校对:张睿毅本文约3200字,建议阅读8分钟 计算类数据科学库,已经不再局限在Pandas、NumPy、Scikit-learn之内了!动机2023年的开始,自然需要探索数据科学和机器学习的新趋势。…

【华为OD机试模拟题】用 C++ 实现 - 分积木(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

Web Spider Ast-Hook 浏览器内存漫游-数据检索

文章目录一、资源下载二、通过npm安装anyproxy模块三、anyproxy的介绍以及基本使用1. anyproxy的功能介绍2. anyproxy的基本使用四、给浏览器挂代理五、实操极验demo案例总结提示:以下是本篇文章正文内容,下面案例可供参考 一、资源下载 Github&#x…

【华为OD机试模拟题】用 C++ 实现 - 符合条件的子串长度(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

【华为OD机试模拟题】用 C++ 实现 - 矩阵最值(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

【华为OD机试模拟题】用 C++ 实现 - 找数字(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

MIND——Modality independent neighbourhood descriptor 模态无关邻域描述符

参考:https://blog.mbedded.ninja/programming/signal-processing/image-processing/image-registration/modality-independent-neighbourhood-descriptor-mind/《MIND: Modality independent neighbourhood descriptor for multi-modal deformable registration》论…

Elasticsearch7.8.0版本进阶——文档分析 分析器

目录一、文档分析过程二、分析器三、内置分析器3.1、标准分析器3.2、简单分析器3.3、空格分析器3.4、语言分析器四、分析器使用场景五、分析器的测试示例一、文档分析过程 将一块文本分成适合于倒排索引的独立的词条。将这些词条统一化为标准格式以提高它们的“可搜索性”&…

JDBC-

文章目录JDBC1,JDBC概述1.1 JDBC概念1.2 JDBC本质1.3 JDBC好处2,JDBC快速入门2.1 编写代码步骤2.2 具体操作3,JDBC API详解3.1 DriverManager3.2 Connection (事务归我管)3.2.1 获取执行对象3.2.2 事务管理3.3 Stateme…

12.STM32系统定时器-SysTick

目录 1.系统定时器-SysTick 2.SysTick定时时间的计算 3.SysTick结构体 4.SysTick固件库函数 5.SysTick中断优先级 1.系统定时器-SysTick SysTick:24位系统定时器,只能递减,存在于内核嵌套在NVIC中。所有的Cortex-M中都有这个系统定时器。 重装载值…

interrupt多线程设计模式

1. 两阶段终止-interrupt Two Phase Termination 在一个线程T1中如何“优雅”终止线程T2?这里的【优雅】指的是给T2一个料理后事的机会。 错误思路 ● 使用线程对象的stop()方法停止线程(强制杀死) —— stop()方法…

会声会影2023电脑版下载及系统配置要求

平时大家可能会经常听到有人说会声会影,但是很多人都不知道这是什么软件。其实听它的名字就知道这是一款和声音、影像有关系的软件。下面,小编就来给大家具体介绍一下这款软件吧。 会声会影是一套操作简单的DV、HDV影片剪辑软件。会声会影不仅完全符合家…