for example:I want to implement an AOP retry function
@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");
}
output:
unAnnotatedMethodC
unAnnotatedMethodB
annotatedMethodA
annotatedMethodA
annotatedMethodA
annotatedMethodA
it has woven twice,its not i hope,i want output like this
unAnnotatedMethodC
unAnnotatedMethodB
annotatedMethodA
annotatedMethodA
How can I avoid this problem?
Your pointcut expression matches both execution
and call
type pointcuts, that's why you get double matches. execution
type pointcuts match the location of the method's bytecode, while call
type pointcuts will match the bytecode of the call sites of code invoking those methods. You'll need to restrict your code to execution
type pointcuts to avoid invoking the around advice twice:
@Pointcut("@annotation(retryed) && execution(* *(..))")
See call vs execution in the AspectJ programming guide for further reference.