Spring AOP:切入点表达式
在本文中,我们将通过示例详细讨论 AOP 切入点表达式。
什么是切入点表达式
spring AOP中的切入点是基于一个称为切入点表达式的表达式来定义的。
这有助于根据表达式中指定的条件查找一组连接点。这些条件有助于定位特定的包、方法、类、注释和 bean。
execution(public int *.*.aopdemo.service.MyServiceImpl.getSum(int,int))
- 切入点指示符 (PCD):PCD(上面以突出显示)有助于将方法、类、包、bean 和注释精确定位为连接点。
- 表达式条件:它(非突出显示)有助于识别哪个特定类、方法、bean 或注释用作连接点。每个PCD具有不同的表达式条件语法。
不同的PCD及其表达式条件语法:
1、execution :
最常用的 PCD,主要用于根据方法查找连接点。
语法: modifiers-pattern? return-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?
这里的修饰符模式(modifiers-pattern)、声明类型模式(declaring-type-pattern)和抛掷模式(throws-pattern)是可选的:
- modifiers-pattern:指定要匹配的方法的访问修饰符。例如,公共、受保护、私有以及*(如有)。
- return-type-pattern:指定要匹配的方法的返回类型,例如void、int、String、Object。* 如果是任何返回类型。
- declaring-type-pattern:它指定声明方法的类型或完全限定类名,例如 com.sample.aopdemo.service.MyServiceImpl 和 * 表示任何类型。
- name-pattern:它指定要匹配的方法的名称,例如,getSum 和* 表示任何方法名称。
- param-pattern:指定要匹配的方法的参数类型,例如,int、String、* 表示任意参数类型,.. 表示任意数量的参数。
- throws-pattern:它指定要匹配的方法抛出的异常的完整限定类名,例如 com.sample.aopdemo.exception.CoderStuffException 和 * 表示任何异常。
execution(public int com.sample.aopdemo.service.MyServiceImpl.getSum(int,int)) |
但也可以根据包和类来搜索连接点。示例:
execution(public * com.sample.aopdemo.controller.MyAppController.*()) |
2、within :
它将指定软件包或类中的所有方法视为连接点。
语法:within(full qualified class name)
示例:
within(com.sample.aopdemo.service.MyServiceImpl) |
3、bean
它将指定 bean 中定义的所有方法都视为连接点。
语法:bean(bean name)
bean(coderstuffservice) |
这会将名为 coderstuffservice 的 bean 中的所有方法都视为连接点。
4、this
它将所有方法都视为指定类实例中的连接点。
语法:this(class qualified name)
this(com.sample.aopdemo.service.MyServiceIntf) |
com.sample.aopdemo.service.MyServiceIntf 是一个接口,其实现由 com.sample.aopdemo.service.MyServiceImpl 类提供。因此它将 com.sample.aopdemo.service.MyServiceImpl 类中的所有方法都视为连结点。
5、annotation
它将所有在其上有指定注解的方法都视为连接点。
语法:@annotation(annotation-type-pattern)
@annotation(org.springframework.web.bind.annotation.GetMapping) |
@Pointcut
在 Spring AOP 中,我们还可以创建一个命名的快捷方式,以便在应用代码中重复使用。@Pointcut 注解有助于实现这一目的。使用 @Pointcut 注解,我们可以为一个点切口命名,并通过其名称重复使用它。示例
@Pointcut("execution(public int *.*.aopdemo.service.MyServiceImpl.*(..))") |
我们可以使用 &&、|| 和 .NET,在一个点切表达式中组合多个点切条件!操作符。示例 :
@Before("this(com.sample.aopdemo.service.MyServiceIntf) && !execution(public int com.sample.aopdemo.service.MyServiceImpl.getSum(int,int))" |
在这里,它会考虑类中所有 com.sample.aopdemo.service.MyServiceIntf 类型的方法,但不会考虑 public int com.sample.aopdemo.service.MyServiceImpl.getSum(int,int) 方法。