所有分类
  • 所有分类
  • 未分类

Spring之AOP–指示器

简介

说明

本文介绍Spring(SpringBoot)的AOP的指示器的使用。

这些指示器可以用在@Around,@Before等括号内,指定切点。

官网

10.2. @AspectJ support – Spring 中文文档

Pointcuts(aspectj官网)

切入点指定者

指示器大全

切入点指定者: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()时,

  1. @target:查看使用方法func()的对象是否有注解;
  2. @within:查看方法func()属于的类是否有注解;
  3. @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?)

除了返回类型模式,名字模式和参数模式以外,所有的部分都是可选的。  ​

0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录