重试工具库二:AOP 结合 guava retryer 实现接口自动重试

上一篇文章中介绍了Retryer 强大的工具库,以及创建方式。重试工具库一: Guava-Retrying

本篇文章我们通过面向切面结合 guava 的这个强大的工具类,来实现只需要添加一行注解即可的自动重试机制。

注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retryer {

	// 指定时间间隔
	long waitMsec() default 0;

	// 重试的异常
	Class[] retryThrowable() default {};

	//在一定超时后停止
	long maxDelayMsec() default 0;

	// 最大重试次数
	int maxAttempt() default 0;
}

AOP切面:

@Aspect
@Component
@Slf4j
public class RetryerAspect {

    @Around(value = "@annotation(Retryer)")
    public Object monitorAround(ProceedingJoinPoint pjp) throws Throwable {
        Method method;
        if (pjp.getSignature() instanceof MethodSignature) {
            MethodSignature signature = (MethodSignature) pjp.getSignature();
            method = signature.getMethod();
        } else {
            log.error("Monitor Annotation not at a method {}", pjp);
            return null;
        }
        Retryer retryerAnnotation = method.getDeclaredAnnotation(Retryer.class);
        if (retryerAnnotation.maxDelayMsec() <= 0 && retryerAnnotation.maxAttempt() <= 1) {
            return pjp.proceed();
        }
        RetryerBuilder retryer = RetryerBuilder.newBuilder();
        if (retryerAnnotation.waitMsec() > 0) {
            retryer.withWaitStrategy(fixedWait(retryerAnnotation.waitMsec(), TimeUnit.MILLISECONDS));
        }
        if (retryerAnnotation.retryThrowable().length > 0) {
            for (Class retryThrowable : retryerAnnotation.retryThrowable()) {
                if (retryThrowable != null && Throwable.class.isAssignableFrom(retryThrowable)) {
                    retryer.retryIfExceptionOfType(retryThrowable);
                }
            }
        }
        if (retryerAnnotation.maxDelayMsec() > 0) {
            retryer.withStopStrategy(StopStrategies.stopAfterDelay(retryerAnnotation.maxDelayMsec(), TimeUnit.MILLISECONDS));
        }
        if (retryerAnnotation.maxAttempt() > 0) {
            retryer.withStopStrategy(StopStrategies.stopAfterAttempt(retryerAnnotation.maxAttempt()));
        }
        String retrylog = pjp.getTarget().getClass().getCanonicalName() + "." + method.getName();
        return retryer.build().call(() -> {
            try {
                log.info("<RETRYER>" + retrylog);
                return pjp.proceed();
            } catch (Throwable throwable) {
                if (throwable instanceof Exception) {
                    throw (Exception) throwable;
                } else {
                    throw new Exception(throwable);
                }
            }
        });
    }
}

使用例子:

 
    
    @Retryer(retryThrowable = Exception.class, maxAttempt = 3,waitMsec = 2000)
    public Object getTest(String hello) {

        Map<String,String> result = null;
        try {

            System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

           result.put("name",hello);
        } catch (Exception e) {
            throw e;
        }
       return "";

    }

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值