SpringAop详解
一、术语解释
@Aspect(切面)
@Pointcut(切点)
1、AspectJ切入点指示符
切入点指示符用来指示切入点表达式目的,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指示符如下:
execution:用于匹配方法执行的连接点
within:用于匹配指定类型内的方法执行
this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配
target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配
args:用于匹配当前执行的方法传入的参数为指定类型的执行方法
@within:用于匹配所以持有指定注解类型内的方法
@target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解
@args:用于匹配当前执行的方法传入的参数持有指定注解的执行
@annotation:用于匹配当前执行方法持有指定注解的方法
bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法
2、类型匹配语法
类型匹配语法
*:匹配任何数量字符;
..:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。
+:匹配指定类型的子类型;仅能作为后缀放在类型模式后边。
使用示例
java.lang.String 匹配String类型;
java.*.String 匹配java包下的任何“一级子包”下的String类型;
如匹配java.lang.String,但不匹配java.lang.ss.String
java..* 匹配java包及任何子包下的任何类型;
如匹配java.lang.String、java.lang.annotation.Annotation
java.lang.*ing 匹配任何java.lang包下的以ing结尾的类型;
java.lang.Number+ 匹配java.lang包下的任何Number的自类型;
如匹配java.lang.Integer,也匹配java.math.BigInteger
Advice(通知)
通知类型 | 术语解释 | 描述 |
---|---|---|
@Before | 前置通知 | 用于定义前置通知,在目标方法执行前执行额外的逻辑。前置通知通常用于在方法执行前做一些准备工作,例如参数验证或日志记录。 |
@AfterReturning | 后置通知 | 用于定义后置通知,在目标方法成功执行后执行额外的逻辑。通常用于处理方法的返回值或执行清理工作。发生异常便不会执行 |
@AfterThrowing | 异常通知 | 用于定义异常通知,它在目标方法抛出异常时执行额外的逻辑。异常通知通常用于记录异常信息或处理异常情况。 |
@After | 最终通知 | 用于定义最终通知,它在目标方法执行后(不论是否发生异常)执行额外的逻辑。最终通知通常用于执行清理工作,例如释放资源。 |
@Around | 环绕通知 | 用于定义环绕通知,它能够完全控制目标方法的执行。环绕通知可以在方法执行前、执行中和执行后执行额外逻辑,它需要显式地调用 ProceedingJoinPoint.proceed() 方法来控制目标方法的执行。 |
二、通知参数
如果想获取被被通知方法参数并传递给通知方法,该如何实现呢?接下来我们将介绍两种获取通知参数的方式。
1. JoinPoint: 提供访问当前被通知方法的目标对象、代理对象、方法参数等数据
package org.aspectj.lang;
import org.aspectj.lang.reflect.SourceLocation;
public interface JoinPoint {
String toString(); //连接点所在位置的相关信息
String toShortString(); //连接点所在位置的简短相关信息
String toLongString(); //连接点所在位置的全部相关信息
Object getThis(); //返回AOP代理对象
Object getTarget(); //返回目标对象
Object[] getArgs(); //返回被通知方法参数列表
Signature getSignature(); //返回当前连接点签名
SourceLocation getSourceLocation();//返回连接点方法所在类文件中的位置
String getKind(); //连接点类型
StaticPart getStaticPart(); //返回连接点静态部分
}
常用API:
方法名 | 描述 |
---|---|
getSignature() | 获取目标方法的方法名、参数类型、返回类型及Class等信息 |
getArgs() | 获取传入目标方法的参数值 |
getTarget() | 获取被代理的对象 |
getThis() | 获取代理对象 |
2. ProceedingJoinPoint: 用于环绕通知,使用proceed()方法来执行目标方法:
public interface ProceedingJoinPoint extends JoinPoint {
public Object proceed() throws Throwable; //执行目标方法
public Object proceed(Object[] args) throws Throwable; //传入新的参数执行目标方法
}
常用API:
方法名 | 描述 |
---|---|
proceed() | 执行目标方法 |
proceed(Object[] args) | 传入新的参数执行目标方法 |
3. JoinPoint.StaticPart: 提供访问连接点的静态部分,如被通知方法签名、连接点类型等
public interface StaticPart {
Signature getSignature(); //返回当前连接点签名
String getKind(); //连接点类型
int getId(); //唯一标识
String toString(); //连接点所在位置的相关信息
String toShortString(); //连接点所在位置的简短相关信息
String toLongString(); //连接点所在位置的全部相关信息
}
提示
- JoinPoint对象封装了SpringAop中切面方法的信息,在切面方法中添加JoinPoint参数,就可以获取到封装了该方法信息的JoinPoint对象。
- ProceedingJoinPoint对象是JoinPoint的子接口,该对象只能用于@Around的环绕切面方法中。