我试图使用aspectJ拦截对实现我的Loggable
接口的类的公共方法的调用。 Loggable是一个标记接口,没有定义任何方法。
我有一个before
建议,我想在其中获取包含正在调用的方法的Concrete类的名称。通过使用thisJoinPoint.getTarget()
,我可以得到具体的类,但是当我调用thisJoinPoint.getTarget().getClass.getName()
时,我得到了一个stackoverflow异常。
我很确定这是因为我在Concrete类上调用了一个公共方法,然后导致我的before
建议重新启动。
这是我的切入点:
pointcut dave() : target(Loggable) && call (public * *(..) ) ;
如何将此限制为仅直接在具体类中定义的公共方法,忽略那些从java.lang.Object继承的公共方法?
答案 0 :(得分:2)
虽然StackOverflow不是一个基于意见的讨论论坛,但我将回答一些具体的例子,以便更加明确:
如果!this(LoggerAspect)
适合您,请使用它。但要注意:当call()
是间接的,即你的建议调用的方法,调用另一种方法时,它不会保持激发建议。
execution()
代替call()
当使用execution()
切入点时,AspectJ仅在被调用者被执行时触发,即在一个单独的地方触发,而不是在调用者调用被调用者的许多地方触发。这样更有效,在这种情况下,你可以为你工作,因为你似乎控制着被调用的代码。只有当weaver /编译器确实可以访问被调用者时,才应该使用call()
切入点来编织调用者。
作为一个副作用,execution()
不会截获第三方库或JDK代码的执行,因为编译器/编织器无法访问它,只有一个例外是第三方库(但不是JDK代码)通过LTW(负载时间编织)编织。
adviceexecution()
切入点通过将您的切入点与&& !adviceexecution()
相结合,您可以在执行call()
时停止发出建议,同时执行任何方面的任何建议。这也排除了间接调用,并且可以很好地用于单个建议。但是,如果你将多个方面结合起来并希望在call()
由另一方面的建议制定时仍然触发你的建议,你可能想要使用其他选项,例如......
within()
切入点通过将您的切入点与&& !within(LoggerAspect)
相结合,您可以在call()
中的任何建议中制作LoggerAspect
时停止发布建议。来自其他方面的电话仍在记录中。
您想要达到的目标决定了您应该选择哪个选项(或其组合)。没有简单的答案,因为我不知道你的具体情况。