1. 切入点的标识符
Spring AOP 中目前只有执行方法这一个连接点,其支持的AspectJ
切入点标识符如下:
标识符 | 功能 |
---|---|
execution | 匹配方法执行的连接点 |
within | 匹配指定的类及其子类中的所有方法 |
this | 匹配可以向上转型为this指定的类型的代理对象中的所有方法 |
target | 匹配可以向上转型为target指定的类型的目标对象中的所有方法 |
args | 匹配运行时传入的参数列表的类型为指定的参数列表类型的方法 |
bean | 匹配特定名称的Bean对象的执行方法,Spring AOP 扩展,AspectJ 没有该指示符 |
@within | 匹配持有指定注解的类的所有方法 |
@target | 匹配持有指定注解目标对象的所有方法 |
@args | 匹配运行时方法传入的参数所属的类持有指定注解的方法 |
@annotation | 匹配持有指定注解的方法 |
2. 常用切入点表达式详解
符号 | 含义 |
---|---|
* | 匹配任意数量字符 |
.. | 匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数 |
+ | 匹配指定类型的子类型,仅能作为后缀放在类型模式后边 |
2.1 execution
execution
的匹配模式是[访问修饰符] [方法返回值] [包名.类名.方法名] (方法参数),除了返回值、方法名和参数外,另外两项都是可选的
#匹配任意类任意返回值任意参数数量及类型的 public 方法
@Before(value = "execution(public * *(..))")
#匹配任意以To为后缀的方法
@Before(value = "execution(* *To(..))")
#匹配Writer接口中及其实现类的方法
@Before(value = "execution(* com.nathan.service.Writer+.*(..))")
#匹配 com.aop.service 包下所有类的所有方法
@Before(value = "execution(* com.nathan.service.*(..))")
# 匹配所有第一个参数为 String 类型,第二个参数为 int 类型的 save 方法
@Before(value = "execution(* save(String,int))")
#匹配除第一个参数固定为 String 外,后面有任意个入参且入参类型不限的 save 方法
@Before(value = "execution(* save(String,..))")
2.2 target
target
表示当被代理的目标对象可以被转换为指定的类型时则匹配成功
#表示匹配实现了 GodService 接口的目标对象的所有方法
@Around(value = "target(nathan.service.GodService)")
2.3 @args
匹配方法传入的参数所属类上拥有指定的注解的情况
# 匹配方法参数类型上拥有 MyAnnotation 注解的方法调用。例如有一个方法add(MyParam param)
#接收一个MyParam类型的参数,而 MyParam 这个类是拥有注解 MyAnnotation 的,则它可以被匹配上
@Around(value = "@args(com.nathan.common.MyAnnotation)")
2.4 @annotation
用于匹配方法上拥有指定注解的情况,最常使用
# 匹配所有拥有 MyAnnotation 注解的外部调用方法
@Around(value="@annotation(com.nathan.common.MyAnnotation)")
3. 增强方法入参配置
对于切面中的一个增强,通常由切入点表达式和增强方法组成,当增强方法需要使用目标方法的相关数据入参时,就可以使用 argNames
配置将其放入增强方法
以下示例中,切入点表达式声明了目标方法必须要同时持有
LogAround
注解和另一个别名 postMapping 类型尚未确定的注解。可以看到argNames
配置了增强方法的参数名称列表,postMapping 的实际类型最终在增强方法的入参中确定,这种配置的实质是绑定参数映射,最终可以实现从目标方法中取得数据填充到增强方法
@Around(value = "@annotation(cn.common.aop.annotation.LogAround) && @annotation(postMapping)", argNames = "pjp,postMapping")
public Object logAround(ProceedingJoinPoint pjp, PostMapping postMapping) throws Throwable {
}