【问题标题】:Before advice getting executed twice...same join point listed twice for same method so it gets called twice在建议执行两次之前...相同的连接点为相同的方法列出了两次,因此它被调用了两次
【发布时间】:2016-08-31 11:11:06
【问题描述】:

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

我们看到每次调用方法都会调用方面两次。

调试它我看到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());
 }

这是我们的自定义注解

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

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

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

这看起来很普通,但显然我做错了什么。任何关于如何每次调用只执行一次建议的建议将不胜感激。

【问题讨论】:

    标签: java aspectj aop aspect


    【解决方案1】:

    您应该打印 Pointcut 并查看如下问题:

    @Before(@annotation(requiresX)”)
    public Object process(ProceedingJoinPoint joinPoint, RequiresACL requiresX) throws Throwable
    {
    
        log.info(" pointcut:" + joinPoint.getKind());
        // do business logic of the aspect…
    
    
     }
    

    它会打印这样的问题:

    pointcut:method-call 
    pointcut:method-execution
    

    所以,你应该把切入点改成:

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

    【讨论】:

      【解决方案2】:

      我们通过反复试验和这篇文章找到了答案:http://forum.spring.io/forum/spring-projects/aop/25729-advice-is-called-twice-with-aop-auto-proxy-configuration

      底线是我们在方面类上有一个@Aspect 注释,并在 Spring XML 文件中指定了方面。不要两者都做。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-24
        • 2022-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多