java - 如何使用AspectJ在java中实现重试机制
问题描述
我正在尝试使用AspectJ
. 如果方法抛出任何异常AspectJ
,则应再次调用方法。
这是我的代码:
重试注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Retry {
int retryCount();
}
重试方面:
@Aspect
public class RetryAspect {
@Around("@annotation(main.Retry)")
public Object profile(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object response = null;
Method method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();
Retry annotation = method.getAnnotation(Retry.class);
int retryCount = annotation.retryCount();
boolean successfull = false;
do{
try {
response = proceedingJoinPoint.proceed();
successfull = true;
}catch(Exception ex){
retryCount--;
if(retryCount < 0){
throw ex;
}
}
}while(!successfull);
return response;
}
}
主要方法:
public class Main {
@Retry(retryCount = 1)
public int method1() throws Exception {
System.out.println("method 1");
throw new Exception();
}
public static void main(String[] args) throws Exception {
Main m = new Main();
boolean successfull = false;
m.method1();
System.out.println("Exit main");
}
}
如果我的理解是正确的,程序应该打印两次“方法 1”并抛出异常。但是“方法 1”被打印了 4 次。这是输出:
method 1
method 1
method 1
method 1
Exception in thread "main" java.lang.Exception
at main.Main.method1_aroundBody0(Main.java:8)
at main.Main.method1_aroundBody1$advice(Main.java:24)
at main.Main.method1(Main.java:1)
at main.Main.method1_aroundBody2(Main.java:14)
at main.Main.method1_aroundBody3$advice(Main.java:24)
at main.Main.main(Main.java:14)
请提及我的实施是否有任何问题。
解决方案
您使用 AspectJ,而不是 Spring AOP,这就是为什么您的切入点匹配两者
call()
(方法调用的来源)和execution()
(目标方法本身)
连接点,因此您会看到 4 个而不是 2 个日志输出。如果您养成在建议开始时(至少在开发期间)始终打印完整连接点(不仅仅是签名或连接点的另一小部分)的习惯,您自己很容易发现。您可以稍后将其注释掉。所以你可以添加
System.out.println(proceedingJoinPoint);
你会明白我的意思。
解决问题的最简单方法是将切入点限制为调用或执行。如果你有选择,我建议后者,因为最好只编织一个方法而不是 100 个调用者。您想将切入点修改为(未经测试,我在路上写“免提”)
@Around("@annotation(main.Retry) && execution(* *(..))")
推荐阅读
- povray - 渲染非常小的物体时没有阴影
- java - 从 main 方法访问抽象类变量
- javascript - 如何存根返回类的类?
- java - 泛型类型实例化和 Lambda
- laravel - 通过第三台服务器对 api 进行 JWT 授权
- html - 带有 Bulma CSS 的 Angular 6 渲染没有 Bulma 样式的 HTML 元素
- google-chrome - 为什么 chrome.sync.set 只更新一次值
- python - 在 pyspark 列中查找列表中连续长度的长度
- google-cloud-platform - 如何使用部署管理器跨区域部署
- powerbi - Power BI - 将数据过滤到当前周(周数)