获取aspectJ建议中的具体类的名称

时间:2016-08-03 15:29:48

标签: java aspectj

我试图使用aspectJ拦截对实现我的Loggable接口的类的公共方法的调用。 Loggable是一个标记接口,没有定义任何方法。

我有一个before建议,我想在其中获取包含正在调用的方法的Concrete类的名称。通过使用thisJoinPoint.getTarget(),我可以得到具体的类,但是当我调用thisJoinPoint.getTarget().getClass.getName()时,我得到了一个stackoverflow异常。

我很确定这是因为我在Concrete类上调用了一个公共方法,然后导致我的before建议重新启动。

这是我的切入点:

pointcut dave() : target(Loggable) && call (public * *(..) ) ;

如何将此限制为直接在具体类中定义的公共方法,忽略那些从java.lang.Object继承的公共方法?

1 个答案:

答案 0 :(得分:2)

虽然StackOverflow不是一个基于意见的讨论论坛,但我将回答一些具体的例子,以便更加明确:

如果!this(LoggerAspect)适合您,请使用它。但要注意:当call()是间接的,即你的建议调用的方法,调用另一种方法时,它不会保持激发建议。

选项1:使用execution()代替call()

当使用execution()切入点时,AspectJ仅在被调用者被执行时触发,即在一个单独的地方触发,而不是在调用者调用被调用者的许多地方触发。这样更有效,在这种情况下,你可以为你工作,因为你似乎控制着被调用的代码。只有当weaver /编译器确实可以访问被调用者时,才应该使用call()切入点来编织调用者。

作为一个副作用,execution()不会截获第三方库或JDK代码的执行,因为编译器/编织器无法访问它,只有一个例外是第三方库(但不是JDK代码)通过LTW(负载时间编织)编织。

选项2:adviceexecution()切入点

通过将您的切入点与&& !adviceexecution()相结合,您可以在执行call()时停止发出建议,同时执行任何方面的任何建议。这也排除了间接调用,并且可以很好地用于单个建议。但是,如果你将多个方面结合起来并希望在call()由另一方面的建议制定时仍然触发你的建议,你可能想要使用其他选项,例如......

选项3:within()切入点

通过将您的切入点与&& !within(LoggerAspect)相结合,您可以在call()中的任何建议中制作LoggerAspect时停止发布建议。来自其他方面的电话仍在记录中。

您想要达到的目标决定了您应该选择哪个选项(或其组合)。没有简单的答案,因为我不知道你的具体情况。