pom依赖
<dependency>
<groupId>com.github.rholder</groupId>
<artifactId>guava-retrying</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
注解类文章来源:https://www.toymoban.com/news/detail-644959.html
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Retryable {
/**
* 需要重试的异常类型
* this.isAssignableFrom(方法抛出的异常) 也就是说,方法抛出的异常必须是retryOn的子类或者子接口
*/
Class<? extends Throwable> retryOn() default Throwable.class;
// 重试次数
int maxAttempts() default 3;
// 重试间隔
long delayMillis() default 1000;
}
import com.github.rholder.retry.RetryException;
import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.github.rholder.retry.WaitStrategies;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
@Aspect
@Order(1)
public class RetryableAspect {
@Around("@annotation(retryable)")
public Object retry(ProceedingJoinPoint joinPoint, Retryable retryable) throws Throwable {
Retryer<Object> retryer = RetryerBuilder.<Object>newBuilder()
.retryIfExceptionOfType(retryable.retryOn())
.withStopStrategy(StopStrategies.stopAfterAttempt(retryable.maxAttempts()))
.withWaitStrategy(WaitStrategies.fixedWait(retryable.delayMillis(), TimeUnit.MILLISECONDS))
.build();
try {
return retryer.call(() -> {
try {
return joinPoint.proceed();
} catch (Exception exception) {
throw exception;
} catch (Throwable e) {
throw new WrapRetryThrowable(e);
}
});
} catch (RetryException e) {
throw e.getLastFailedAttempt().getExceptionCause();
}
}
public static class WrapRetryThrowable extends Exception {
public WrapRetryThrowable(Throwable cause) {
super(cause);
}
}
}
测试类文章来源地址https://www.toymoban.com/news/detail-644959.html
在这里插入代码片@RestController
public class RetryController {
/**
* 顶级异常类测试
* @return
* @throws Throwable
*/
@Retryable(
retryOn = Exception.class,
maxAttempts = 3,
delayMillis = 1000
)
@GetMapping("/throwable")
public String performTask() throws Throwable {
System.out.println("performTask" + System.currentTimeMillis());
// 在这里实现可能抛出异常的业务逻辑
throw new Throwable("error");
}
/**
* 异常类测试
* @return
* @throws CustomException
*/
@Retryable(
retryOn = CustomException.class,
maxAttempts = 2,
delayMillis = 1000
)
@GetMapping("/customException")
public void customException() {
System.out.println("customException" + System.currentTimeMillis());
// 在这里实现可能抛出异常的业务逻辑
}
// 抛出的异常跟枚举异常不一致,不会重试
@Retryable(
retryOn = CustomException.class,
maxAttempts = 3,
delayMillis = 1000
)
@GetMapping("/customException2")
public String customException2() throws Exception {
System.out.println("customException2" + System.currentTimeMillis());
// 在这里实现可能抛出异常的业务逻辑
throw new Exception("这是一段自定义异常的抛出");
}
}
到了这里,关于基于 Guava Retry 在Spring封装一个重试功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!