核心逻辑就是把重试的业务与重试中断条件抽象出来函数化,内部重试业务具体化。
关键需要理解Java的函数式接口编程 Supplier 与 Predicate作用。
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.Random;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* @author zhe.xiao
* @version 1.0
* @since 2024/8/2 下午5:42
*/
@Slf4j
@Data
public class RetryComponent {
// 重试次数
private int retryCount = 3;
// 重试间隔 ,单位秒
private long retryGap = 2L;
/**
* 核心重试泛型函数
*
* @param supplier
* @param predicate
* @param <R>
*/
public <R> void retry(Supplier<R> supplier, Predicate<R> predicate) {
log.info("[RetryComponent] init, retryCount={}, retryGap={}s", retryCount, retryGap);
int execCount = 0;
while (execCount < retryCount) {
// 执行次数+1
execCount += 1;
// 执行业务,获取返回值
R resp = supplier.get();
log.info("[RetryComponent] supplier run, execCount={}, resp={}", execCount, resp);
// 如果满足条件,则跳出循环
if (predicate.test(resp)) {
log.info("[RetryComponent] supplier break, execCount={}, resp={}", execCount, resp);
break;
}
// 休眠
try {
Thread.sleep(retryGap * 1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("[RetryComponent] sleep error", e);
}
}
log.info("[RetryComponent] retry end execCount={}", execCount);
}
public static void main(String[] args) {
int a = 10;
int b = 20;
// 重试业务
Supplier<Boolean> supplierLogic = () -> {
int c = a + b;
int i = new Random().nextInt(50);
System.out.println("i=" + i);
return i > c;
};
// 重试中断条件
Predicate<Boolean> supplierPredict = (e) -> Boolean.TRUE.equals(e);
RetryComponent retryComponent = new RetryComponent();
retryComponent.retry(supplierLogic, supplierPredict);
}
}
692

被折叠的 条评论
为什么被折叠?



