[译] AOP-通知

 声明通知Adivce

Advice 与切入点表达式相关联,并在切入点匹配的方法执行之前、之后或周围运行。切入点表达式可以是对命名切入点的简单引用,也可以是就地声明的切入点表达式。

Before Adivce

您可以使用@Before注释在方面中声明Before Advice:

java

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;@Aspect
public class BeforeExample {@Before("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")public void doAccessCheck() {// ...}
}

如果我们使用inline切入点表达式,我们可以将前面的示例重写为以下示例:

java

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;@Aspect
public class BeforeExample {@Before("execution(* com.xyz.myapp.dao.*.*(..))")public void doAccessCheck() {// ...}
}

After Returning Advice

返回通知后,当匹配的方法执行正常返回时运行。您可以使用@AfterReturning注解来声明它:

java

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;@Aspect
public class AfterReturningExample {@AfterReturning("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")public void doAccessCheck() {// ...}
}

你可以有多个通知声明(以及其他成员),都在同一个方面。我们在这些示例中只展示了一个通知声明,以集中每个通知的效果。

有时,您需要在通知正文中访问返回的实际值。您可以使用@AfterReturning绑定返回值的形式来获取该访问权限,如以下示例所示:

java

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;@Aspect
public class AfterReturningExample {@AfterReturning(pointcut="com.xyz.myapp.CommonPointcuts.dataAccessOperation()",returning="retVal")public void doAccessCheck(Object retVal) {// ...}
}

  • returning属性中使用的名称必须与通知方法中的参数名称相对应。
  • 当目标方法执行返回时,返回值作为相应的参数值传递给该通知方法。
  • returning子句还将匹配并限制那些返回值为指定类型方法执行(在这种情况下,Object匹配任何返回值)。

请注意,在使用 AfterReturning Advice时,不能返回完全不同类型的引用。

After Throwing Advice

当匹配的方法执行抛出异常退出时,After Throwing Advice执行。您可以使用@AfterThrowing注解来声明它,如以下示例所示:

java

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;@Aspect
public class AfterThrowingExample {@AfterThrowing("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")public void doRecoveryActions() {// ...}
}

通常,您希望建议仅在引发指定类型的异常时运行,并且您还经常需要访问Advice中引发的异常。您可以使用该throwing属性来限制匹配(如果需要 -Throwable 用作异常类型)并将抛出的异常绑定到通知参数。以下示例显示了如何执行此操作:

java

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;@Aspect
public class AfterThrowingExample {@AfterThrowing(pointcut="com.xyz.myapp.CommonPointcuts.dataAccessOperation()",throwing="ex")public void doRecoveryActions(DataAccessException ex) {// ...}
}

throwing属性中使用的名称必须与advice方法中参数的名称相对应。当通过引发异常退出方法执行时,异常作为相应的参数值传递给通知方法。throwing子句还限制只匹配那些引发指定类型的异常(在本例中是DataAccessException)的方法执行

After (Finally) Advice

当匹配的方法执行退出时(最终)通知运行。它是通过使用@After注解来声明的。After通知在方法执行正常和异常返回情况下都能够正常处理。它通常用于释放资源和类似目的。下面的例子展示了如何使用 after advice:

java

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;@Aspect
public class AfterFinallyExample {@After("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")public void doReleaseLock() {// ...}
}

请注意,@After

AspectJ 中的通知被定义为“在 finally 通知之后”,类似于 try-catch 语句中的 finally 块。

它将在连接点(用户声明的目标方法)抛出的任何结果、正常返回或异常时调用,与之相反,

@AfterReturning

它仅适用于成功的正常返回。

Around Advice

最后一种AdviceAround AdviceAround Advice“围绕”匹配方法的执行。它在方法运行之前和之后进行工作,并确定该方法何时、如何以及是否真正开始运行。如果您需要以线程安全的方式在方法执行之前和之后共享状态(例如,启动和停止计时器),则通常使用环绕通知。

始终使用满足您要求的最不强大的建议形式。例如,如果之前的建议足以满足您的需求,请不要使用环绕建议。

环绕通知是通过使用@Around注解对方法进行注解来声明的。该方法应声明Object为其返回类型,并且该方法的第一个参数必须是ProceedingJoinPoint类型。在通知方法的主体中,您必须调用ProceedingJoinPoint对象的proceed()方法使目标方法运行。不带参数调用proceed()将导致调用者的原始参数在调用时提供给底层方法。对于高级用例,该proceed()方法有一个重载变体,它接受参数数组 ( Object[])。调用时,数组中的值将用作底层方法的参数。

当用Object[] 调用时,proceed的行为与由aspectj编译器编译的around advice的proceed的行为稍有不同。对于使用传统aspectj语言编写的around advice,传递给proceed的参数数量必须与传递给around advice的参数数量(而不是基础连接点接受的参数数量) 匹配,并且传递给给定参数位置的值在连接点为值所绑定到的实体添加原始值(如果现在没有意义,请不要担心) 。

Spring采用的方法更简单,更符合其基于代理的、只执行的语义。只有在编译为Spring编写的@Aspectj方面并使用aspectj编译器和weaver的参数时,才需要注意这一区别。有一种方法可以在SpringAOP和AspectJ中编写100%兼容的方面,这将在下面关于建议参数的小节中讨论。

around 通知返回的值是方法调用者看到的返回值。例如,一个简单的缓存方面可以从缓存中返回一个值,如果它有一个值,或者调用proceed()(并返回该值)如果它没有。请注意,proceed 在 around 建议的主体内可能会调用一次、多次或根本不调用。所有这些都是合法的。

如果您将around建议方法的返回类型声明为void,那么null将始终返回给调用者,从而有效地忽略任何processed()调用的结果。因此,建议around建议方法声明Object的返回类型。

advice方法通常应该返回从processed()的调用返回的值,即使基础方法的返回类型为void。但是,根据使用情况,建议可以选择性地返回缓存值、包装值或其他值。

下面的例子展示了如何使用 around 通知:

java

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;@Aspect
public class AroundExample {@Around("com.xyz.myapp.CommonPointcuts.businessService()")public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {// start stopwatchObject retVal = pjp.proceed();// stop stopwatchreturn retVal;}
}

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

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

相关文章

现在的00后,实在是太卷了......

现在的小年轻真的卷得过分了。前段时间我们公司来了个00年的,工作没两年,跳槽到我们公司起薪18K,都快接近我了。后来才知道人家是个卷王,从早干到晚就差搬张床到工位睡觉了。 最近和他聊了一次天,原来这位小老弟家里条…

1688平台商品实时详情API接口演示,1688详情页接口,接口key和secret获取方式

1688商品详情API接口的重要性主要体现在以下几个方面: 提高营销效率:通过1688商品详情API接口,商家可以快速获取商品的详细信息,了解市场需求,制定更为精准的营销策略。优化客户服务:商家可以通过API接口为…

Java中各种数据类型之间的转换

低类型向高类型自动进行转换,高类型向低类型的准换会丢失数据,整数到字符类型的转换将获取对应编码的字符。 进行高精度向低精度的强制类型准换时,需要将想要转换成的数据类型加一个括号()。 如何完成自动转换呢? 转换前的数据类…

KNN算法实战-健康医疗

健康医疗 算法建模 knn 算法建模构建微观数据和疾病之间的关系knn 调整超参数,准确率提升数据归一化、标准化,提升更加明显 算法实战 导入包 import numpy as np import pandas as pd from sklearn.neighbors import KNeighborsClassifier from sklea…

LeetCode 每日一题 Day 3||深度优先搜索(DFS)

1038. 从二叉搜索树到更大和树 给定一个二叉搜索树 root (BST),请将它的每个节点的值替换成树中大于或者等于该节点值的所有节点值之和。 提醒一下, 二叉搜索树 满足下列约束条件: 节点的左子树仅包含键 小于 节点键的节点。节点的右子树仅…

【23-24 秋学期】NNDL 作业12 优化算法2D可视化

简要介绍图中的优化算法,编程实现并2D可视化 1. 被优化函数 2. 被优化函数 3. 解释不同轨迹的形成原因 分析各个算法的优缺点 REF:图灵社区-图书 (ituring.com.cn) 深度学习入门:基于Python的理论与实现 NNDL 作业11:优化算…

Redis系列之incr和decr命令是线程安全的?

Redis是一个单线程的服务,所以正常来说redis的命令是会排队执行的。incr/decr命令是redis提供的可以实现递增递减的命令,所以这两个命令也是具有原子性的?是线程安全的?这个也是互联网公司面试的常见题,话不多说&#…

Leetcode 108 将有序数组转换为二叉搜索树

题意理解: 我们需要根据一个数组来构建一个二叉搜索树,且该二叉搜索树也是高度平衡二叉树。 什么是高度平衡二叉树呢? 即对于每个节点来说,左右子树高度差不超过1 思路:我们总是从数组的中间位置作为根节点构建该树,这…

AcW730.机器人跳跃问题(二分法)-Java版

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;//由题目可知,无论能量大与小,都满足 e 2 * e - h[i]; //初始能量越大,最终的结果越大,要找到一个满足条件的最小值 //可以根据二分的向左找模板: /*if(check(mid)) r mid;els…

茄子科技张韶全:跨多云大数据平台DataCake在OceanBase的实践

11 月 16 日,OceanBase 在北京顺利举办 2023 年度发布会,正式宣布:将持续践行“一体化”产品战略,为关键业务负载打造一体化数据库。其中,在“数字化转型升级实践专场”,我们有幸邀请到了茄子科技大数据技术…

一个Blazor+WinForm+MAUI+PDA实现的条码比对系统

条码比对系统是由单机版桌面软件和Android版的PDA扫码软件组成,桌面软件采用Blazor与WinForm进行混合开发,PDA扫码软件采用MAUI进行开发,这个项目都是基于.NET技术进行构建,这也是将近期学习Blazor和MAUI这两门技术应用到实践当中…

刷题系列——排序算法

参考:README - 十大经典排序算法 1)排序算法分为内部外部排序两种,这个之前并不了解,外部排序需要访问外存的这个就是指需要额外内存比如另一个list或者dict存储中间结果。 2)稳定性:排序后 2 个相等键值…

openGauss训练营培训课程第1课时

课时1:openGauss全景介绍 1、介绍 openGauss 全景 1.1.openGauss总体架构介绍 本章节主要介绍了openGauss发展的历史,现状以及未来。对当前的DataPod和DataKit 2种openGauss当前主推的场景化产品进行了介绍。同时对openGauss的整个逻辑模块的视图进行了讲解。 …

[NOIP2001 提高组] 一元三次方程求解

[NOIP2001 提高组] 一元三次方程求解 题目描述 有形如: a x 3 b x 2 c x d 0 a x^3 b x^2 c x d 0 ax3bx2cxd0 这样的一个一元三次方程。给出该方程中各项的系数( a , b , c , d a,b,c,d a,b,c,d 均为实数),并约定该方程…

算法通关村第十三关-黄金挑战数论问题

计数质数 描述 : 给定整数 n ,返回 所有小于非负整数 n 的质数的数量 。 题目 : LeetCode 204.计数质数 : 204. 计数质数 分析 : 解决这个题有一个有效的方法,叫埃氏筛 , 后来又产生了线性筛,奇数筛等改进的方法。 基本思想是如果 x是…

12.04 二叉树中等题

513. 找树左下角的值 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1 思路:找到最低层中最左侧的节点值,比较适合层序遍历,返回最…

【动态规划】LeetCode-198/LCR089.打家劫舍

🎈算法那些事专栏说明:这是一个记录刷题日常的专栏,每个文章标题前都会写明这道题使用的算法。专栏每日计划至少更新1道题目,在这立下Flag🚩 🏠个人主页:Jammingpro 📕专栏链接&…

MS85163实时时钟/日历可Pin to Pin兼容PCF8563

MS85163/MS85163M是一款CMOS实时时钟(RTC) 和日历电路,针对低功耗进行了优化,内置了可编程的时钟输出、中断输出和低电压检测器。可Pin to Pin兼容PCF8563。所有寄存器地址和数据都通过两线双向I 2C总线进行串行传输,最大总线传输速度为 400k…

2023年【上海市安全员C3证】新版试题及上海市安全员C3证试题及解析

题库来源:安全生产模拟考试一点通公众号小程序 上海市安全员C3证新版试题是安全生产模拟考试一点通总题库中生成的一套上海市安全员C3证试题及解析,安全生产模拟考试一点通上上海市安全员C3证作业手机同步练习。2023年【上海市安全员C3证】新版试题及上…

干货分享:盘点8款优秀的自动化测试工具

如今,作为一名软件测试工程师,几乎所有人都需要具备自动化测试相关的知识,并且懂得如何去利用工具,来为企业减少时间成本和错误成本。这是为什么呢? 在以前,测试人员一般都只需要扮演终端用户,…