AOP详解

一.什么是 AOP?

AOP 的目的是将横切关注点(如日志记录、事务管理、权限控制、接口限流、接口幂等等)从核心业务逻辑中分离出来,通过动态代理、字节码操作等技术,实现代码的复用和解耦,提高代码的可维护性和可扩展性。OOP 的目的是将业务逻辑按照对象的属性和行为进行封装,通过类、对象、继承、多态等概念,实现代码的模块化和层次化(也能实现代码的复用),提高代码的可读性和可维护性。

二.AOP 关键术语

  • 横切关注点(cross-cutting concerns) :多个类或对象中的公共行为(如日志记录、事务管理、权限控制、接口限流、接口幂等等)。
  • 切面(Aspect):对横切关注点进行封装的类,一个切面是一个类。切面可以定义多个通知,用来实现具体的功能。
  • 连接点(JoinPoint):连接点是方法调用或者方法执行时的某个特定时刻(如方法调用、异常抛出等)。

    连接点是程序执行过程中可以插入一个切面的具体位置。简单地说,连接点是程序中可以应用通知(Advice)的点。连接点的例子包括方法调用、方法执行、构造器调用、构造器执行、字段访问等。在 Spring AOP 中,连接点主要指方法执行。

    例如,在下面的类中:

    public class AccountService {public void deposit(double amount) {// ...}public void withdraw(double amount) {// ...}
    }

    deposit 和 withdraw 方法的调用和执行就是连接点。

  • 通知(Advice):通知就是切面在某个连接点要执行的操作。通知有五种类型,分别是前置通知(Before)、后置通知(After)、返回通知(AfterReturning)、异常通知(AfterThrowing)和环绕通知(Around)。前四种通知都是在目标方法的前后执行,而环绕通知可以控制目标方法的执行过程。
  • 切点(Pointcut):一个切点是一个表达式,它用来匹配哪些连接点需要被切面所增强。切点可以通过注解、正则表达式、逻辑运算等方式来定义。比如 execution(* com.xyz.service..*(..))匹配 com.xyz.service 包及其子包下的类或接口。

切点(Pointcut)

切点是一个匹配连接点的集合,它是一个表达式,用于选择一组连接点。切点定义了在那些连接点上应用通知。切点表达式可以基于方法名称、方法参数、注解、包名等进行匹配。

例如,下面的切点表达式匹配 AccountService 类中的所有方法:

@Pointcut("execution(* com.example.service.AccountService.*(..))")
public void allAccountServiceMethods() {}

这个切点定义了匹配 com.example.service.AccountService 类的所有方法调用的连接点。

  • 连接点(Join Point): 程序中的一个点,这个点可以被增强(例如方法调用、方法执行、字段访问)。就是类中的方法
  • 切点(Pointcut): 用于定义哪些特定的连接点会被增强的表达式。它是从一组连接点中过滤出需要增强的子集。在AOP中我们定义的要增强的方法

  • 织入(Weaving):织入是将切面和目标对象连接起来的过程,也就是将通知应用到切点匹配的连接点上。常见的织入时机有两种,分别是编译期织入(Compile-Time Weaving 如:AspectJ)和运行期织入(Runtime Weaving 如:AspectJ、Spring AOP)。

三.AOP 常见的通知类型有哪些?

 

  • Before(前置通知):目标对象的方法调用之前触发
  • After (后置通知):目标对象的方法调用之后触发
  • AfterReturning(返回通知):目标对象的方法调用完成,在返回结果值之后触发
  • AfterThrowing(异常通知):目标对象的方法运行中抛出 / 触发异常后触发。AfterReturning 和 AfterThrowing 两者互斥。如果方法调用成功无异常,则会有返回值;如果方法抛出了异常,则不会有返回值。
  • Around (环绕通知):编程式控制目标对象的方法调用。环绕通知是所有通知类型中可操作范围最大的一种,因为它可以直接拿到目标对象,以及要执行的方法,所以环绕通知可以任意的在目标对象的方法调用前后搞事,甚至不调用目标对象的方法

@Pointcut是定义哪些切点要执行AOP功能,@Before/after是定义具体哪些方法在前/后……执行,后者的参数是前者的子集

四.注解

`@Pointcut` 是 AspectJ 框架中的一个注解,用于定义切入点 (Pointcut)。切入点是指那些可以插入切面(Aspect)的具体位置或情况。使用 `@Pointcut` 注解可以让你在代码中更灵活地定义哪些方法或代码块将应用特定的切面逻辑。是用来定义哪些方法会自动使用我们AOP封装的功能

以下是一些使用 `@Pointcut` 的主要用法:

基本定义

你可以使用 `@Pointcut` 注解来定义一个简单的切入点。下面是一个基本示例,定义了一个切入点,该切入点匹配所有 `public` 访问修饰符的 `find*` 方法:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoggingAspect {

    @Pointcut("execution(public * find*(..))")
    private void allFindMethods() {
        // pointcut signature method
    }
}
 

使用其他注解

你也可以结合其他注解来更灵活地定义切入点。比如,你可以定义一个切入点,匹配所有带有特定注解的类或方法:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoggingAspect {

    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
    private void allGetMappingMethods() {
        // pointcut signature method
    }
}
 

结合使用多个切入点

你还可以结合多个切入点来定义更复杂的匹配条件。下面是一个示例,结合了两个不同的切入点:

```java
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoggingAspect {

    @Pointcut("execution(public * *(..))")
    private void anyPublicOperation() {}

    @Pointcut("within(com.example.myapp.service..*)")
    private void inServiceLayer() {}

    @Before("anyPublicOperation() && inServiceLayer()")//这里的before,after就是上面介绍的通知类型,用来定义方法什么时候执行AOP封装的功能,前/后/……
    public void logBefore() {
        System.out.println("Logging before a public service method");
    }
}
```

### 切入点表达式

切入点表达式是 `@Pointcut` 注解字符串值中的一种语言。以下是一些常见的语法:

- `execution(<method-pattern>)`:匹配某个方法的执行。
- `within(<type-pattern>)`:匹配某个类型中的所有方法。
- `this(<type>)`:匹配所有实现给定接口的目标实例。
- `target(<type>)`:匹配给定类型的目标实例。
- `args(<argument-types>)`:匹配参数为指定类型的方法。

@annotation:按注解进行方法匹配,比如

 @Pointcut("@annotation(MyCustomAnnotation)")

AOP匹配所有有 MyCustomAnnotation注解的方法

总结来说,切入点是AOP中的核心概念之一, `@Pointcut` 注解让切入点的定义变得灵活且易于管理, 从而实现代码的关注点分离,提升代码的可维护性和可读性。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

红队知识学习入门(4)Windows病毒编写

声明 学习视频来自B站UP主 泷羽sec,如涉及侵泷羽sec权马上删除文章笔记的只是方便各位师傅学习知识,以下网站涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 1、端口号及对应漏洞 ftp:21 tenlnet:23 web:80 80-89:可能是web 443&#xff1a;ssl心脏滴血…

知识竞赛答题系统,线上答题小程序链接怎么做?

随着智能手机的普及&#xff0c;越来越多的单位开始在线上开展知识竞赛。这种形式的知识竞赛不仅易于操作&#xff0c;而且参与度更高。那么线上知识竞赛答题系统怎么做呢&#xff1f;自己可以做吗&#xff1f;答案是可以的&#xff01;借助微信答题系统制作平台风传吧&#xf…

AndroidStudio通过Bundle进行数据传递

作者&#xff1a;CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 使用环境&#xff1a;AndroidStudio 目录 1.新建活动 2.修改页面布局 代码&#xff1a; 效果&#xff1a; 3.新建类ResultActivity并继承AppCompatActivity 4.新建布局文件activity_result.xml 代…

【网络-交换机】生成树协议、环路检测

路由优先级 路由优先级决定了在多种可达的路由类型中&#xff0c;哪种路由将被用来转发数据包。路由优先级值越低&#xff0c;对应路由的优先级越高&#xff0c;优先级值255表示对应的路由不可达。一般情况下&#xff0c;静态路由的优先级为1&#xff0c;OSPF路由优先级为110&a…

华为eNSP:mux-vlan

一、什么是mux-vlan&#xff1f; Mux-vlan 是一种多路复用的虚拟局域网&#xff08;Virtual Local Area Network&#xff09;技术。它将多个不同的VLAN流量转发到同一个物理端口&#xff0c;从而实现VLAN间的互通。 在传统的以太网环境中&#xff0c;每个VLAN通常都有一个独立…

又发现了Mac妙控鼠标的新使用方法

我一直是不爱用妙控鼠标的&#xff0c;因为用起来怪怪的&#xff0c;但是今天发现BettreAndBetter支持妙控鼠标的修改&#xff0c;于是就找出了闲置了许久的妙控鼠标试了一下 优化后的妙控鼠标使用起来就没有任何不适应的地方了&#xff0c;三指按下模拟中键&#xff0c;而且还…

Cursor编程工具

最近爆火的Cursor是一款基于 VS Code 二次开发的 AI 编辑器。相比传统编辑器&#xff0c;它将 AI 技术深度融合到各个功能点&#xff0c;带来了前所未有的用户体验。 下载链接&#xff1a;https://www.cursor.com/ 第一步&#xff1a;下载安装 下载完成后&#xff0c;双击启动…

Me-LLaMA——用于医疗领域的新型开源大规模语言模型

摘要 大规模语言模型的出现是提高病人护理质量和临床操作效率的一个重大突破。大规模语言模型拥有数百亿个参数&#xff0c;通过海量文本数据训练而成&#xff0c;能够生成类似人类的反应并执行复杂的任务。这在改进临床文档、提高诊断准确性和管理病人护理方面显示出巨大的潜…

鸿蒙ArkTS中的布局容器组件(Column、Row、Flex、 Stack、Grid)

在鸿蒙ArkTS中&#xff0c;布局容器组件有很多&#xff0c;常见的有&#xff1a;   ⑴ Column&#xff1a;&#xff08;垂直布局容器&#xff09;&#xff1a;用于将子组件垂直排列。   ⑵ Row&#xff1a;&#xff08;水平布局容器&#xff09;&#xff1a;用于将子组件水…

【点击劫持漏洞(附测试代码)】

漏洞描述 点击劫持&#xff08;Clickjacking&#xff09;是一种网络攻击技术&#xff0c;攻击者通过将一个恶意的页面或按钮隐藏在合法网站的页面下&#xff0c;诱使用户在不知情的情况下点击隐藏的内容&#xff0c;从而触发攻击者设计的操作。这种攻击通常会导致用户无意中执…

大数据新视界 -- 大数据大厂之经典案例解析:电商企业如何靠 Impala性能优化逆袭(上)(9/30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

语音 AI 迎来爆发期,也仍然隐藏着被低估的机会丨RTE2024 音频技术和 Voice AI 专场

在人工智能快速发展的今天&#xff0c;语音交互技术正经历一场革命性的变革。从语音识别到语音合成&#xff0c;再到端到端的语音对话系统&#xff0c;这一领域的创新正以前所未有的速度推进。这些进步不仅提升了技术指标&#xff0c;更为实时翻译、虚拟数字人、智能客服等实时…

vue3 + ts + element-plus 二次封装 el-table

一、实现效果&#xff1a; &#xff08;1&#xff09;数据为空时&#xff1a; &#xff08;2&#xff09;有数据时&#xff1a;存在数据合并&#xff1b;可自定义表头和列的内容 &#xff08;3&#xff09;新增行&#xff1a; &#xff08;4&#xff09;删除行&#xff1a; &a…

6 张图带你深入了解 kube-scheduler

本文目录&#xff1a; kube-scheduler 用途Scheduler Pod 调度流程源码调用链路Scheduler Framework如何扩展 kube-scheduler 用途 顾名思义&#xff1a;负责将 Pod 调度到 Node 上。 Pod 创建流程&#xff1a; 说明&#xff1a; 所有的组件只与 Apiserver 做交互&#xff0…

数据结构(8.7_1)——外部排序

知识总览 外存、内存之间的数据交换 外部排序原理 构造初始“归并段” 第一趟归并 第二趟归并 输出缓冲区1空了用归并段1的下一块元素补上 ..... 顺序的两个归并段方法一样..... 第三趟归并 时间开销分析 对外部排序进行优化 由于文件总块数无法改变&#xff0c;所以…

“方块兽神仙猿点石成金”游戏搭建开发

“方块兽神仙猿点石成金”是一款结合了策略和运气的休闲游戏。玩家需在规定时间内向不同的山头投入矿石&#xff0c;等待神仙猿降临并随机选择一座山进行“点石成金”。根据神仙猿的选择&#xff0c;玩家将获得不同的奖励。 游戏核心机制 矿石投入&#xff1a;玩家在游戏开始…

【压力测试】如何确定系统最大并发用户数?

一、明确测试目的与了解需求 明确测试目的&#xff1a;首先需要明确测试的目的&#xff0c;即为什么要确定系统的最大并发用户数。这通常与业务需求、系统预期的最大用户负载以及系统的稳定性要求相关。 了解业务需求&#xff1a;深入了解系统的业务特性&#xff0c;包括用户行…

达梦数据库DM管理工具增删改不生效怎么办?如何设置事务自动提交?

前言 我在使用达梦数据库DM时&#xff0c;一开始使用的是达梦数据库自带的连接工具DM管理工具。自带的有它自己的好处&#xff0c;起码对于修改新增字段等是比较兼容的。后面我发现DBeaver也是支持连接达梦数据库的&#xff0c;所以后面用DBeaver也在连接达梦数据库。 我在一…

JVM出现OOM错误排查

前言 对应线程出现的OOM错误&#xff0c;其实分好几类&#xff1a;堆内存溢出、栈溢出、方法区溢出&#xff0c;下面我们要区分两个概念 内存泄漏&#xff1a; 内存泄漏是指GC垃圾回收的速度跟不上内存消耗的速度,造成OOM的情况 内存溢出: 内存溢出是指程序员在申请内存时&…

WinForms 中使用 MVVM 模式构建应用:实现登录页面、页面导航及 SQLite 数据库连接完整框架搭建过程

前言 在传统的 WinForms 应用程序开发中&#xff0c;很多开发者使用事件驱动的设计模式&#xff0c;直接将业务逻辑编写在界面代码中。然而&#xff0c;随着应用程序的复杂性增加&#xff0c;单一的界面文件变得臃肿&#xff0c;难以测试和维护。借鉴 WPF 中 MVVM&#xff08;…