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;
        
    }
}