简介
说明
本文介绍Spring(SpringBoot)的AOP的指示器的使用。
这些指示器可以用在@Around,@Before等括号内,指定切点。
官网
10.2. @AspectJ support – Spring 中文文档
切入点指定者
指示器大全
切入点指定者:pointcut designators(pcd)
AspectJ指示器 | 描述 |
arg() | 限制连接点匹配参数为指定类型的执行方法 |
@args() | 限制连接点匹配参数由指定注解标注的执行方法 |
execution() | 用于匹配是连接点的执行方法 |
this() | 限制连接点匹配AOP代理的bean引用为指定类型的类 |
target | 限制连接点匹配目标对象为指定类型的类 |
@target() | 限制连接点匹配执行对象的类带有指定注解。 |
within() | 限制连接点匹配指定的类 |
@within() | 限制连接点匹配带有指定注解的类。 |
@annotation | 限定匹配带有指定注解的方法。 |
bean | 限制连接点匹配的特定命名的 Spring bean。格式:bean(idOrNameOfBean) 这是 Spring 特有的。(对 AspectJ 定义的 PCD 的扩展) |
@target、@within、@annotation的区别:
当执行son.func()时,
- @target:查看使用方法func()的对象是否有注解;
- @within:查看方法func()属于的类是否有注解;
- @annotation:查看方法func()是否有注解;
备注
完整的 AspectJ 切入点语言支持额外的切入点指定者,但是 Spring 不支持这个功能。 它们分别是call, get, set, preinitialization, staticinitialization, initialization, handler, adviceexecution, withincode, cflow, cflowbelow, if, @this, 和 @withincode 。 在 Spring AOP 中使用这些指定者将会导致抛出IllegalArgumentException 异常。
示例
任意 public 方法的执行:
execution(public * *(..))
任何一个以“set”开始的方法的执行:
execution(* set*(..))
AccountService 接口的任意方法的执行:
execution(* com.xyz.service.AccountService.*(..))
定义在service包里的任意方法的执行:
execution(* com.xyz.service.*.*(..))
定义在service包或者子包里的任意方法的执行:
execution(* com.xyz.service..*.*(..))
在service包里的任意方法 :
within(com.xyz.service.*)
在service包或者子包里的任意方法 :
within(com.xyz.service..*)
实现了 AccountService 接口的代理对象的任意方法 :
this(com.xyz.service.AccountService)
‘this’在binding form中用的更多。
实现了 AccountService 接口的目标对象的任意方法 :
target(com.xyz.service.AccountService)
‘target’在binding form中用的更多。
任何一个只接受一个参数,且在运行时传入的参数实现了 Serializable 接口的方法
args(java.io.Serializable)
‘args’在binding form中用的更多。
请注意在例子中给出的切入点不同于 execution(* *(java.io.Serializable))只有在动态运行时候传入参数是可序列化的(Serializable)才匹配,而 execution 在传入参数的签名声明的类型实现了 Serializable 接口时候匹配。
有 @Transactional 注解的目标对象中的任意方法
@target(org.springframework.transaction.annotation.Transactional)
‘@target’ 也可以在binding form中使用。
列表里任何一个目标对象声明的类型有 @Transactional 注解的方法
@within(org.springframework.transaction.annotation.Transactional)
‘@within’也可以在binding form中使用。
任何一个执行的方法有 @Transactional注解的方法
@annotation(org.springframework.transaction.annotation.Transactional)
‘@annotation’ 也可以在binding form中使用。
任何一个接受一个参数,并且传入的参数在运行时的类型实现了 @Classified注解 的方法
@args(com.xyz.security.Classified)
‘@args’也可以在binding form中使用。
任何 Spring bean 命名为 tradeService 的方法:
bean(tradeService)
任何 Spring bean 命名符合正则表达式为 *Service 的方法:
bean(*Service)
合并切入点表达式
可以使用 &&, || 和 ! 来合并,还可以通过名字来指向切入点表达式。
以下的例子展示了三种切入点表达式:
//代表了任意 public 方法的执行时匹配 @Pointcut("execution(public * *(..))") private void anyPublicOperation() {} //在指定包中的任意的方法执行时匹配 @Pointcut("within(com.xyz.someapp.trading..*)") private void inTrading() {} //指定包任意的公共方法执行时匹配 @Pointcut("anyPublicOperation() && inTrading()") private void tradingOperation() {}
@Pointcut("execution(* *(..,com.example.a,..)) && " + "(@annotation(org.springframework.web.bind.annotation.RequestMapping) || " + "@annotation(org.springframework.web.bind.annotation.GetMapping) ||" + "@annotation(org.springframework.web.bind.annotation.PostMapping) ||" + "@annotation(org.springframework.web.bind.annotation.PutMapping) ||" + "@annotation(org.springframework.web.bind.annotation.DeleteMapping) ||" + "@annotation(org.springframework.web.bind.annotation.PatchMapping))")
execution
格式
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
除了返回类型模式,名字模式和参数模式以外,所有的部分都是可选的。
请先
!