java基于Spring AOP手写一个重试机制

定义了一个名为Retryable的注解,用于标记需要进行重试的方法,最大重试次数和可重试的异常类型可配置。RetryAspect切面负责拦截这些方法并在出现特定异常时执行重试逻辑。示例中,@Retryable注解用于一个GET请求方法,当发生BizException时进行重试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retryable {
    int maxAttempts() default 3; // 最大重试次数
    Class<? extends Throwable>[] retryOn() default Exception.class; // 需要重试的异常类型
}
  1. 切面RetryAspect,用于拦截Retryable注解的方法并执行重试逻辑
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;


@Aspect
@Component
public class RetryAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(RetryAspect.class);

    @Around("@annotation(retryable)")
    public Object retry(ProceedingJoinPoint joinPoint, Retryable retryable) throws Throwable {
        int maxAttempts = retryable.maxAttempts();
        Class<? extends Throwable>[] retryOn = retryable.retryOn();
        int attempts = 0;
        do {
            attempts++;
            try {
                return joinPoint.proceed();
            } catch (Throwable e) {
                boolean retry = false;
                for (Class<? extends Throwable> exception : retryOn) {
                    if (exception.isInstance(e)) {
                        retry = true;
                        break;
                    }
                }
                if (!retry || attempts >= maxAttempts) {
                    throw e;
                }
                LOGGER.warn("Retry attempt {} for method {}", attempts, joinPoint.getSignature().toShortString());
            }
        } while (attempts < maxAttempts);
        throw new IllegalStateException("Unreachable");
    }
}
  1. 使用注解(注意异常)

    @GetMapping("/test")
    @Retryable(maxAttempts = 3, retryOn = {BizException.class})
    public void authtest() {
        try {
            String res = HttpUtil.get("http://localhost:8080/test");
            JSONObject jsonObject = JSONObject.parseObject(res);
            //todo ....
        } catch (Exception e) {
            throw new BizException("请求未正常返回");
        }
    }

当然还有可以直接使用Spring-Retry去直接处理这个逻辑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值