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