[英]How to implement Retry mechanism in java using AspectJ
I am trying to implement Retry mechanism using AspectJ
.我正在尝试使用
AspectJ
实现重试机制。 If a method throws any exception AspectJ
should invoke method once again.如果方法抛出任何异常,
AspectJ
应该再次调用方法。
Here is my code:这是我的代码:
Retry annotation:重试注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Retry {
int retryCount();
}
Retry aspect:重试方面:
@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;
}
}
main method:主要方法:
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");
}
}
If my understanding is correct program should print "method 1" twice and throw exception.But "method 1" is getting printed 4 times.如果我的理解是正确的,程序应该打印两次“方法 1”并抛出异常。但是“方法 1”被打印了 4 次。 Here is output:
这是 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)
Please mention if there is any wrong with my implementation.请提及我的实施是否有任何问题。
You use AspectJ, not Spring AOP, which is why your pointcut matches both您使用 AspectJ,而不是 Spring AOP,这就是为什么您的切入点同时匹配
call()
(the source of the method call) and call()
(方法调用的来源)和execution()
(the target method itself) execution()
(目标方法本身) joinpoints, thus you see 4 instead of 2 log outputs.连接点,因此您会看到 4 个而不是 2 个日志输出。 You could have found out by yourself easily if you would have made it a habit to always print the full joinpoint (not just the signature or another small part of the joinpoint) at the beginning of your advice, at least during development.
如果您养成在建议开始时(至少在开发期间)始终打印完整连接点(不仅仅是签名或连接点的另一小部分)的习惯,您自己很容易发现。 You can comment it out later.
您可以稍后将其注释掉。 So you can just add
所以你可以添加
System.out.println(proceedingJoinPoint);
and you will see what I mean.你会明白我的意思。
The easiest way to fix the problem is to limit the pointcut to either calls or executions.解决问题的最简单方法是将切入点限制为调用或执行。 I suggest the latter if you have a choice, because it is better to just weave one method instead of 100 callers.
如果你有选择,我建议后者,因为最好只编织一个方法而不是 100 个调用者。 You want to modify your pointcut to (untested, I am writing "hands-free" on the road)
您想将切入点修改为(未经测试,我在路上写“免提”)
@Around("@annotation(main.Retry) && execution(* *(..))")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.