例如:我想实现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
它编织了两次,不是我希望的,我想要这样的输出
unAnnotatedMethodC
unAnnotatedMethodB
annotatedMethodA
annotatedMethodA
如何避免这个问题?
答案 0 :(得分:0)
您的切入点表达式同时匹配execution
和call
类型的切入点,这就是为什么您会获得双重匹配的原因。 execution
类型切入点与方法的字节码的位置匹配,而call
类型切入点将与调用这些方法的代码的调用位置的字节码匹配。您需要将代码限制为execution
类型的切入点,以避免两次调用周围的建议:
@Pointcut("@annotation(retryed) && execution(* *(..))")
有关更多参考,请参见AspectJ编程指南中的call vs execution。