[英]How to implement Retry mechanism in java using AspectJ
我正在嘗試使用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 次。 這是 output:
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(* *(..))")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.