1 The annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface NeedToRetry {
Class<?>[] recoverableExceptions();
int retryTime();
int intervalIncrementalFactor() default 0;
long retryInterval() default 0L;
}
2 The Aspect
@Aspect
public class InvokingRetryInterceptor {
private static Logger log = Logger.getLogger(InvokingRetryInterceptor.class);
private boolean isNeedToRetry(Throwable t,Class<?>[] recoverableExceptions){
String exceptionName= t.getClass().getName();
for (Class<?> exp:recoverableExceptions){
if (exp.isInstance(t)){
return true;
}
}
log.warn("The exception doesn't need recover!"+exceptionName);
return false;
}
private long getRetryInterval(int tryTimes,long interval,int incrementalFactor){
return interval+(tryTimes*incrementalFactor);
}
@Around(value="@annotation(amazon.internal.dropship.common.NeedToRetry)&&@annotation(retryParam)",argNames="retryParam")
public Object process(ProceedingJoinPoint pjp,NeedToRetry retryParam ) throws Throwable{
boolean isNeedTry=true;
int count=0;
Throwable fault;
Class<?>[] recoverableExceptions=retryParam.recoverableExceptions();
int retryTime=retryParam.retryTime();
long retryInterval=retryParam.retryInterval();
int incrementalFactor=retryParam.intervalIncrementalFactor();
do{
try{
return pjp.proceed();
}catch(Throwable t){
fault=t;
if (!isNeedToRetry(t,recoverableExceptions)){
break;
}
Thread.sleep(getRetryInterval(retryTime,retryInterval,incrementalFactor));
}
count++;
}while(count<(retryTime+1));
throw fault;
}
}