Aspectj编织了带注释的方法A和方法B调用方法A

时间:2019-02-13 06:19:01

标签: aop aspectj

例如:我想实现AOP重试功能

@Pointcut("@annotation(retryed)")
public void retry(Retry retryed) {}

@Around("retry(retryed)")
public Object process(ProceedingJoinPoint pjp, Retry retryed) throws Throwable {
    Object result = null;
    for (int i = 0; i < 2; i++) {
        result = pjp.proceed();
    }
    return result;
}



@Test
public void test() throws Exception {
    unAnnotatedMethodC();
}
private void unAnnotatedMethodC() {
    System.out.println("unAnnotatedMethodC");
    unAnnotatedMethodB();
}
private void unAnnotatedMethodB() {
    System.out.println("unAnnotatedMethodB");
    annotatedMethodA();
}
@Retry
private void annotatedMethodA() {
    System.out.println("annotatedMethodA");
}

输出:

unAnnotatedMethodC
unAnnotatedMethodB
annotatedMethodA
annotatedMethodA
annotatedMethodA
annotatedMethodA

look the .class file

它编织了两次,不是我希望的,我想要这样的输出

unAnnotatedMethodC
unAnnotatedMethodB
annotatedMethodA
annotatedMethodA

如何避免这个问题?

1 个答案:

答案 0 :(得分:0)

您的切入点表达式同时匹配executioncall类型的切入点,这就是为什么您会获得双重匹配的原因。 execution类型切入点与方法的字节码的位置匹配,而call类型切入点将与调用这些方法的代码的调用位置的字节码匹配。您需要将代码限制为execution类型的切入点,以避免两次调用周围的建议:

@Pointcut("@annotation(retryed) && execution(* *(..))")

有关更多参考,请参见AspectJ编程指南中的call vs execution