У меня есть аннотация:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Retry {
int DEFAULT_RETRIES = 2;
int times() default DEFAULT_RETRIES;
}
Который используется либо на уровне класса:
@Retry(times = 5)
public class PersonServiceClass {
//...
public void deletePerson(long id) {
//...
}
}
Или уровень метода (другой класс, а не PersonServiceClass):
@Retry
public void deletePerson(long id) {
//...
}
Аспект ловится таким классом:
@Aspect
@Component
public class RetryInterceptor {
@Around("@within(retry) || @annotation(retry)")
public Object around(ProceedingJoinPoint proceedingJoinPoint, Retry retry) throws Throwable {
System.out.println("around - " + retry);
System.out.println("joinpoint - " + proceedingJoinPoint);
return aroundHandler(proceedingJoinPoint, retry);
}
И аспект правильно перехватывается на уровне метода или класса, но что-то не так с привязкой аннотации Retry.
Когда @Around выглядит следующим образом: @Around("@within(retry) || @annotation(retry)"), тогда:
retry имеет значение связанный.retry имеет значение нулевой.Когда @Around выглядит следующим образом @Around("@annotation(retry) || @within(retry)"), тогда:
retry имеет значение нулевой.retry имеет значение связанный.Родительская версия Spring Boot — 2.1.1.RELEASE
"|" недействительный токен
... да, это был гатшот: || && ! - единственные операнды...




...теперь ты бросил мне вызов :) и я может воспроизвести проблему!
Прагматически я (бы) решил (d) это так:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class ExampleAspect {
@Around("@within(retry)")
public Object typeAspect(ProceedingJoinPoint joinPoint, Retry retry) throws Throwable {
return commonAspect(joinPoint, retry);
}
@Around("@annotation(retry)")
public Object methodAspect(ProceedingJoinPoint joinPoint, Retry retry) throws Throwable {
return commonAspect(joinPoint, retry);
}
private Object commonAspect(ProceedingJoinPoint joinPoint, Retry retry) throws Throwable {
System.out.println("Retry is :" + (retry == null ? "null" : retry.value()));
// ... do your (common) stuff here
return proceed;
}
}
..Добро пожаловать! :-)
А так как у вас уже есть (распространенный) метод aroundHandler(), то сводится к тому, чтобы "ввести для него 2 общедоступных фасада/PCD".
Дополнительный совет: переименуйте times() (если это единственное/основное свойство этой аннотации) в: value()! .. тогда вы можете сделать "просто" @Retry(100).
Вы «пытались» использовать (неэффективный)
|(или, который оценивает обе стороны) вместо||(«эффективный»)? ...может это не баг, а фича!? :)