静下心来的个人专栏
上一篇

Spring AOP 中的切入点表达式

广告
选中文字可对指定文章内容进行评论啦,→和←可快速切换按钮,绿色背景文字可以点击查看评论额。
大纲

Spring AOP 中的切入点表达式

简介

在本文中,您将了解用于将通知与目标连接点匹配的切入点表达式。 Spring AOP 使用 AspectJ 切入点表达式。您学习过切入点定义。 Spring AOP 仅支持方法执行连接点,因此您可以将切入点视为匹配 Spring bean 上方法的执行。

切入点:它是一个确定连接点的谓词表达式,因此允许我们控制通知的执行。

简单来说,切入点表达式就像一个正则表达式,它决定了将执行 Advice 的类和方法。

声明切入点

声明切入点很简单,您只需要使用@Pointcut(POINTCUT_EXPRESSION) 注释方法即可。

@Pointcut("execution(* transfer(..))") // the pointcut expression
private void anyTransfer() {}   //pointcut signature

使用@Pointcut 是可选的,切入点表达式可以直接在通知注释中使用,如下所示。

  • Before advice –@Before
  • Around advice – @Around
  • After returning – @AfterReturning
  • After throwing – @AfterThrowing
  • After (finally) advice – @After
@Before("execution(* c.jbd.saop.gettingstarted.dao.*.add(..))")
public void allRepoAddMethods(JoinPoint joinPoint) {
  //Aspect body
}

@Before 或 @Pointcut 注释中的术语执行称为切入点指示符。 Spring 提供了几个接下来要讨论的指示符。

支持的切入点指示符

Spring AOP 支持以下切入点指示符 (PCD)。

execution - 用于匹配方法执行连接点。这是使用最广泛的 PCD。

within - 用于匹配某些类型内的类的方法,例如包内的类。

@within - 用于匹配具有给定注释的类型(目标对象类)内的连接点。

this - 用于匹配连接点(方法的执行),其中 bean 引用(Spring AOP 代理)是给定类型的实例。

target - 用于匹配特定实例类型的目标对象。

@target – 用于匹配带有特定注释的目标对象。

args - 用于匹配其参数为特定类型的方法。

@args - 用于匹配使用特定注释注释其参数的方法。

@annotation - 用于匹配连接点的主题(方法)具有给定注释的连接点。

bean (idOrNameOfBean) – 此 PCD 允许您将连接点的匹配限制为特定命名的 Spring bean 或一组命名的 Spring bean(使用通配符时)。

AspectJ 提供了其他几个 Spring AOP 不支持的指示符,只支持上面提到的 PCD。

 

组合切入点表达式

您可以使用 AND – &&, OR – || 组合多个切入点表达式并不是 - !。您还可以按名称引用切入点表达式。以下示例显示相同:

@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {} 
@Pointcut("within(com.jsbd.trading..*)")
private void inTrading() {} 
@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {} 

各种切入点指示符示例

execution designator

这是大家需要知道的最广泛使用的指示符,用来匹配方法执行Joinpoint。 execution() 指示符的语法将在下面讨论。

execution(modifiers-pattern? return-type-pattern declaring-type-pattern? name-pattern( param-pattern)
  throws-pattern?)
  1. modifiers-pattern - Method visibility (public, protected, private, *) ret-type-pattern - Return type of the method
  2. declaring-type-pattern - Package or class (ex: com.app.service.* - applies to all classes in this package, com.app.service.UserService - applies only to UserService class, * - all)
  3. name-pattern - method name (ex: set* - all setters)
  4. param-pattern - method parameters (.. - any number of parameters, java.lang.String - method taking String as parameter.
  5. throws-pattern - Method throwing this exception.

? – 表示可选指定,例如修饰符, throws_exception

* – 模式中的星号代表通配符

() – 对于 parameter_pattern 表示没有参数

(..) – 用于匹配具有零个或多个任意类型参数的 parameter_pattern

(*) – 模式匹配采用任何类型的一个参数的方法。

(*, String) - 匹配带有两个参数的方法,第一个是任意类型,第二个参数是字符串类型。

在下表中,我向您展示了一些最常用的示例,以便您更好地理解执行指示符。单词any代表下表中的所有。

ExplanationPattern
To match with the execution of any public methodexecution(public * *(..))
The match with any setterexecution(* set*(..))
Match with any method inside ActorRepository, defined inside a particular packageexecution(* c.jbd.saop.gettingstarted.dao.ActorRepository.*(..)
Match with any DAO delete() method with any type of arguments."execution(* c.jbd.app.dao.*.*(..))"
Match any method inside any DAO with exactly one argument of any type."execution(* c.jbd.saop.gettingstarted.dao.*.*(*))"

 

within and @within designators

within 用于匹配某些类型中的类的方法,例如包内的类。

类似地,@within 用于匹配目标对象的声明类具有给定注释的连接点(方法执行)。

ExplanationPattern
Match with any joinpoint within business package."within(com.jbd.business.*)"
Match with any joinpoint within business and its sub-packages"within(com.jbd.business..*)"
Match with any join point (method) execution where the declared type of the target object (the class) has an @Transactional annotation."@within( org.springframework.transaction.annotation.Transactional )"

The this designator

它将匹配限制为连接点(方法的执行),其中 bean 引用(Spring AOP 代理)是给定类型的实例。

例如,匹配代理实现 AccountService 接口的任何连接点(方法执行)。

"this(com.jbd.service.AccountService)"

The target and @target designators

目标指示符将匹配限制为目标对象(被代理的应用程序对象)是给定类型的实例的连接点(方法的执行)。例如当目标对象实现特定接口时。

例如,目标对象实现 AccountService 接口的任何连接点。

"target(com.jbd.service.AccountService)"

类似地,@target 用于将匹配限制为连接点(方法的执行),其中执行对象的类具有给定类型的注释。

例如,目标对象具有@Transactional 注释的任何连接点。

"@target(org.springframework.transaction.annotation.Transactional)"

The args and @args designators

args 将匹配限制为连接点(方法的执行),其中参数是给定类型的实例。

例如,任何采用单个参数并且在运行时传递的参数是可序列化的连接点(方法执行)。

同样,args 将匹配限制为连接点,其中传递的实际参数的运行时类型具有给定类型的注释。

例如,任何接受单个参数的连接点(方法执行),并且传递的参数的运行时类型具有 @Classified 注释:

"@args(com.jbd.security.Classified)"

The @annotation designator

@annotation 指示符将匹配限制为连接点的主题(正在执行的方法)具有给定注释的连接点。

注意:@annotation 限制了方法具有给定注释的连接点的匹配,而 @within 匹配如果类具有注释。

例如,匹配执行方法具有@Transactional 注释的任何连接点(方法执行)。

"@annotation(org.springframework.transaction.annotation.Transactional)"

The bean Pointcut designator

bean PCD 允许您将连接点的匹配限制为特定命名的 Spring bean 或一组命名的 Spring bean(使用通配符时)。

例如,Spring bean 上的任何连接点(方法执行),其名称与通配符表达式 *Manager 匹配。

"bean(*Manager)"

另一个示例,Spring bean 名称为 accountRepository 的任何连接点。

"bean(accountRepository)"

总结

从可读性的角度来看,我建议保持 Pointcut 表达式简单,同时确保编译器更容易缩小 Joinpoint 扫描的范围。例如。使用 with 或 @within 执行。

版权声明:著作权归作者所有。

X

欢迎加群学习交流

联系我们