Spring 在带有注解的字段上调用的方法的 AOP 切入点
Spring AOP Pointcut for methods invoked on field with annotation
我正在编写一个方面,使从外部库到为我的应用程序正确格式化的 return 值的依赖成为可能。
考虑到这一点,我创建了一个名为 @SafeReturns. 的注释
我在 spring 的帮助下从外部库连接这个 class,此外,我添加了我的注释。
@SafeReturns
@Autowired
public PermissionsClient client;
现在我尝试做一个方面,但不幸的是,我无法捕获对使用此注释注释的字段上所有方法的所有调用。我尝试了不同的切入点。例如
@Pointcut("execution(@myApp.SafeReturns * *(..))")
@Around("safeReturnsPointCut()")
public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {
}
None 帮助我实现捕获所有方法的行为。有办法抓住他们吗?
您的方法以及您对方面语法和执行逻辑的假设存在几个问题:
您正在使用 Spring AOP,但由于其基于代理的性质,该 AOP 仅适用于 Spring-managed beans/components,有据可查在 Spring AOP manual。它不适用于非Spring第三方代码。
为了以第三方代码为目标,您需要通过 LTW(加载时织入)使用完整的 AspectJ。 Spring AOP手册也解释了how to configure LTW.
你的切入点说要针对所有方法执行(Spring 组件,如果你使用 Spring AOP),其中方法由 SafeReturns
注释。无论是使用 Spring AOP 还是使用 AspectJ,您都不能期望此语法适用于恰好分配给具有特定注释的实例成员变量的对象。因此,您对 AOP 的理想工作方式和实际工作方式的期望大相径庭。
我的建议是通过 LTW 切换到 AspectJ,然后编写直接针对外部方法 execution()
s 的切入点,或者通过带注释的外观路由外部调用并使用切入点定位它们来间接解决问题.如果外观是 Spring 组件,这甚至可以与 Spring AOP 一起使用。
还有一种直接的方法可以使用高级 AspectJ + 一些手动簿记来解决此问题。您可以使用 set()
切入点来查明对象何时分配给您的注释字段(或稍后未分配)。然后,您可以让方面对分配的对象进行手动簿记,并确保只有当所讨论的对象恰好被分配给带注释的成员变量时,您的方面建议才会被触发。这行得通,我过去也这样做过。但这意味着您必须编织应用程序的所有方法调用,然后通过簿记中的查找动态决定代码是否应该执行,因为您可能会有未分配给任何带注释的对象实例领域。这会导致一定的性能损失,因为这种事情无法在编译期间由任何方面编织器确定。请参阅 my answer here 以获取手动记账的示例代码。
我希望我的解释不是太复杂,但你的问题是非常技术性的和复杂的。
我正在编写一个方面,使从外部库到为我的应用程序正确格式化的 return 值的依赖成为可能。
考虑到这一点,我创建了一个名为 @SafeReturns. 的注释 我在 spring 的帮助下从外部库连接这个 class,此外,我添加了我的注释。
@SafeReturns
@Autowired
public PermissionsClient client;
现在我尝试做一个方面,但不幸的是,我无法捕获对使用此注释注释的字段上所有方法的所有调用。我尝试了不同的切入点。例如
@Pointcut("execution(@myApp.SafeReturns * *(..))")
@Around("safeReturnsPointCut()")
public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {
}
None 帮助我实现捕获所有方法的行为。有办法抓住他们吗?
您的方法以及您对方面语法和执行逻辑的假设存在几个问题:
您正在使用 Spring AOP,但由于其基于代理的性质,该 AOP 仅适用于 Spring-managed beans/components,有据可查在 Spring AOP manual。它不适用于非Spring第三方代码。
为了以第三方代码为目标,您需要通过 LTW(加载时织入)使用完整的 AspectJ。 Spring AOP手册也解释了how to configure LTW.
你的切入点说要针对所有方法执行(Spring 组件,如果你使用 Spring AOP),其中方法由
SafeReturns
注释。无论是使用 Spring AOP 还是使用 AspectJ,您都不能期望此语法适用于恰好分配给具有特定注释的实例成员变量的对象。因此,您对 AOP 的理想工作方式和实际工作方式的期望大相径庭。
我的建议是通过 LTW 切换到 AspectJ,然后编写直接针对外部方法 execution()
s 的切入点,或者通过带注释的外观路由外部调用并使用切入点定位它们来间接解决问题.如果外观是 Spring 组件,这甚至可以与 Spring AOP 一起使用。
还有一种直接的方法可以使用高级 AspectJ + 一些手动簿记来解决此问题。您可以使用 set()
切入点来查明对象何时分配给您的注释字段(或稍后未分配)。然后,您可以让方面对分配的对象进行手动簿记,并确保只有当所讨论的对象恰好被分配给带注释的成员变量时,您的方面建议才会被触发。这行得通,我过去也这样做过。但这意味着您必须编织应用程序的所有方法调用,然后通过簿记中的查找动态决定代码是否应该执行,因为您可能会有未分配给任何带注释的对象实例领域。这会导致一定的性能损失,因为这种事情无法在编译期间由任何方面编织器确定。请参阅 my answer here 以获取手动记账的示例代码。
我希望我的解释不是太复杂,但你的问题是非常技术性的和复杂的。