简体   繁体   English

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

[英]Before advice getting executed twice…same join point listed twice for same method so it gets called twice

We're implemented "before" advice using custom annotations so as to only execute certain methods if the (uninteresting to this problem) business logic applies. 我们使用自定义注释实现“之前”建议,以便仅在(对此问题不感兴趣)业务逻辑适用时才执行某些方法。

We're seeing the aspect called twice for each invocation of the method. 我们看到每次调用方法时调用两次方面。

Debugging into it I see Cglib2AopProxy$CglibMethodInvocation.proceed has an array called: interceptorsAndDynamicMethodMatchers . 调试它我看到Cglib2AopProxy$CglibMethodInvocation.proceed有一个名为: interceptorsAndDynamicMethodMatchers的数组。 This array lists our PointCut ("RequiresX") twice. 这个数组列出了我们的PointCut ("RequiresX")两次。

Here is the join point: 这是连接点:

@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());
 }

and here is our custom annotation 这是我们的自定义注释

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.Method)
public @interface RequiresX {
}

and here is a method we can to intercept: 这是我们可以拦截的方法:

@RequiresX()
public String someMethod() {    
    ....
}

This seems pretty vanilla but clearly I've done something wrong. 这看起来很香草,但显然我做错了什么。 Any suggestions on how to only execute the advice once per call would be greatly appreciated. 关于如何每次通话只执行一次建议的任何建议都将不胜感激。

you should print Pointcut and see the problem like: 你应该打印Pointcut并看到问题,如:

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

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


 }

it will print the problem like: 它将打印问题,如:

pointcut:method-call 
pointcut:method-execution

So, you should change Pointcut as: 所以,你应该改变Pointcut为:

@Before(@annotation(RequiresX) && execution(@RequiresX * *.*(..)))

We found the answer both via trial and error and via this post: http://forum.spring.io/forum/spring-projects/aop/25729-advice-is-called-twice-with-aop-auto-proxy-configuration 我们通过试验和错误以及通过这篇文章找到答案: http//forum.spring.io/forum/spring-projects/aop/25729-advice-is-called-twice-with-aop-auto-proxy-组态

Bottom line is we had an @Aspect annotation on the aspect class as well as specifying the aspect in the Spring XML file. 底线是我们在方面类上有一个@Aspect注释,并在Spring XML文件中指定方面。 Don't do both. 不要两者都做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM