Spring AOP不能双重绑定注释
我有注释:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Retry {
int DEFAULT_RETRIES = 2;
int times() default DEFAULT_RETRIES;
}
在课程级别上使用哪个:
Which is used either on class level:
@Retry(times = 5)
public class PersonServiceClass {
//...
public void deletePerson(long id) {
//...
}
}
或方法级别(另一个类,而不是PersonServiceClass):
Or method level (another class, not 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批注存在某些问题.
And aspect is correctly caught on method or class level, but there is something wrong with binding Retry annotation.
当@Around如下时:@Around("@within(retry) || @annotation(retry)")然后:
- 在方法级别被捕获时,
retry被绑定 - 在课堂上被捕获时,
retry为空.
- When caught on method level than
retryis binded - When caught on class level than
retryis null.
当@Around遵循@Around("@annotation(retry) || @within(retry)")时,则:
- 在方法级别被捕获时,
retry为空. - 在课堂上被捕获时,
retry被绑定.
- When caught on method level than
retryis null. - When caught on class level than
retryis binded.
Spring Boot父版本-2.1.1.RELEASE
...now you challenged me:) and i could reproduce the issue!
实用的我会这样解决(d):
Pragmatically I (would) solve(d) it like that:
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;
}
}
..欢迎光临! :-)
..welcome! :-)
由于您已经有一个(通用的)aroundHandler()方法,因此可以归结为为此引入2个公共外观/PCD".
And since you already have a (common) aroundHandler() method, it comes down to "introducing 2 public facades/PCDs for it".
其他提示:将times()(如果它是该注释的唯一/主要属性)重命名为:value()! ..然后您可以仅"执行@Retry(100).
Additional hint: Rename times() (if its the only/main property of that annotation) to: value()! ..then you can do "just" @Retry(100).