在两次执行建议之前...对于相同的方法两次列出相同的连接点,因此两次被调用

Bri*_*box 2 java aop aspectj aspect

我们使用自定义注释实现了“之前”建议,以便仅在应用(对此问题不感兴趣)业务逻辑时执行某些方法。

我们看到该方法的每次调用都调用了两次方面。

调试它时,我看到Cglib2AopProxy$CglibMethodInvocation.proceed有一个名为:的数组 interceptorsAndDynamicMethodMatchers。该数组列出了PointCut ("RequiresX")两次。

这是连接点:

@Before(@annotation(requiresX)”)
public Object process(ProceedingJoinPoint joinPoint, RequiresACL requiresX) throws Throwable
{
    Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
    log.info(" method:" + method.getName());

    // do business logic of the aspect…

    log.info(" joinPoint.proceed with call to " + method.getName());
 }
Run Code Online (Sandbox Code Playgroud)

这是我们的自定义注释

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.Method)
public @interface RequiresX {
}
Run Code Online (Sandbox Code Playgroud)

这是我们可以拦截的方法:

@RequiresX()
public String someMethod() {    
    ....
}
Run Code Online (Sandbox Code Playgroud)

这似乎很香草,但显然我做错了。任何关于如何在每次呼叫中仅执行一次建议的建议将不胜感激。

use*_*888 7

您应该打印Pointcut并看到类似的问题:

@Before(@annotation(requiresX)”)
public Object process(ProceedingJoinPoint joinPoint, RequiresACL requiresX) throws Throwable
{

    log.info(" pointcut:" + joinPoint.getKind());
    // do business logic of the aspect…


 }
Run Code Online (Sandbox Code Playgroud)

它将显示以下问题:

pointcut:method-call 
pointcut:method-execution
Run Code Online (Sandbox Code Playgroud)

因此,您应该将Pointcut更改为:

@Before(@annotation(RequiresX) && execution(@RequiresX * *.*(..)))
Run Code Online (Sandbox Code Playgroud)