Java編寫自定義重試工具類的示例代碼
Java重試工具類,零依賴??膳渲庙棧航邮艿漠惓n愋?、返回值校驗、最大重試次數(shù)、重試間隔時間。
1 重試工具類 RetryUtils源碼
RetryUtils:
使用了lombok的@Slf4j注解用于打印日志,不用可移除。
import com.example.exception.RetryException;
import lombok.extern.slf4j.Slf4j;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* <h2>重試工具類</h2>
*
* @author GFire
* @since 2025/4/22 17:58
*/
@Slf4j
public abstract class RetryUtils {
/**
* 失敗重試
*
* @param task 執(zhí)行的任務(wù),無返回值
* @param acceptException 可接受的異常類型,執(zhí)行的任務(wù)拋出此異常(及其子類)則失敗重試。null表示不接受任何異常
* @param maxRetryCount 最大重試次數(shù)
* @param waitTime 重試間隔等待時間, 單位毫秒, <=0則不等待
* @throws RetryException 如果任務(wù)重試超過最大次數(shù)、或拋出不可接受的異常,則統(tǒng)一包裝拋出RetryException
*/
public static void doWithRetry(Runnable task, Class<? extends Throwable> acceptException, int maxRetryCount, int waitTime) {
if (task == null) {
throw new IllegalArgumentException("task can not be null");
}
doWithRetry(() -> {
task.run();
return 1;
}, i -> i == 1, acceptException, maxRetryCount, waitTime);
}
/**
* 失敗重試
*
* @param task 執(zhí)行的任務(wù),有返回值
* @param isValid 判斷任務(wù)返回值是否合法,不合法則失敗重試
* @param acceptException 可接受的異常類型,執(zhí)行的任務(wù)拋出此異常(及其子類)則失敗重試。null表示不接受任何異常
* @param maxRetryCount 最大重試次數(shù)
* @param waitTime 重試間隔等待時間, 單位毫秒, <=0則不等待
* @return supplier執(zhí)行結(jié)果
* @throws RetryException 如果任務(wù)重試超過最大次數(shù)、或拋出不可接受的異常,則統(tǒng)一包裝拋出RetryException
*/
public static <T> T doWithRetry(Supplier<T> task, Predicate<T> isValid, Class<? extends Throwable> acceptException, int maxRetryCount, int waitTime) {
if (task == null) {
throw new IllegalArgumentException("task can not be null");
}
if (isValid == null) {
throw new IllegalArgumentException("isValid can not be null");
}
if (maxRetryCount <= 0) {
throw new IllegalArgumentException("maxRetryCount must be > 0");
}
T result = null;
for (int tryCount = 1; tryCount <= maxRetryCount; tryCount++) {
try {
result = task.get();
if (isValid.test(result)) {
return result;
} else {
log.error("result invalid, tryCount: {}, result: {}", tryCount, result);
}
} catch (Throwable e) {
handleException(e, acceptException, maxRetryCount, tryCount);
}
if (waitTime > 0 && tryCount < maxRetryCount) {
sleep(waitTime); // 等待一段時間后重試
}
}
throw new RetryException("result: " + result);
}
private static void handleException(Throwable e, Class<? extends Throwable> acceptException, int maxRetryCount, int tryCount) {
log.error("error, tryCount: {}, Exception: ", tryCount, e);
if (acceptException != null && acceptException.isInstance(e)) {
if (tryCount == maxRetryCount) { // 最后一次重試仍失敗,則拋出
throw new RetryException(e);
}
} else { // 不可接受的異常,直接拋出
throw new RetryException(e);
}
}
private static void sleep(int waitTime) {
try {
Thread.sleep(waitTime);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RetryException(e);
}
}
}
RetryException:
/**
* <h2>重試異常</h2>
*
* @author GFire
* @since 2025/4/23 11:20
*/
public class RetryException extends RuntimeException {
public RetryException(String message) {
super(message);
}
public RetryException(Throwable cause) {
super(cause);
}
}
2 使用方式
示例1:任務(wù)無返回值
// 模擬調(diào)用API接口,失敗重試 RetryUtils.doWithRetry(() -> apiService.query(), Exception.class, 3, 2000);
解釋:任務(wù)apiService.query()無返回值、接受Exception異常、最大重試次數(shù)為3、重試間隔2秒
示例2:任務(wù)有返回值、需校驗返回值
/**
* 模擬發(fā)送通知
*/
public boolean send(String content) {
try {
RetryUtils.doWithRetry(() -> noticeService.send(content), this::isValid, Exception.class, 3, 2000);
return true;
} catch (RetryException e) {
log.error("send error: {}", e.toString());
}
return false;
}
private boolean isValid(String res) {
if (StringUtils.isNotEmpty(res)) {
JSONObject response = JSON.parseObject(res);
return "ok".equals(response.getString("status"));
}
return false;
}
解釋:任務(wù)noticeService.send(content)有String類型的返回值、isValid方法判斷返回值是否合法、接受Exception異常、最大重試次數(shù)為3、重試間隔2秒
示例3:任務(wù)有返回值、無需校驗返回值
RetryUtils.doWithRetry(() -> noticeService.send(), (res) -> true, Exception.class, 3, 2000);
解釋:任務(wù)noticeService.send()有String類型的返回值、(res) -> true認(rèn)為任意返回值都合法(即無校驗)、接受Exception異常、最大重試次數(shù)為3、重試間隔2秒
到此這篇關(guān)于Java編寫自定義重試工具類的示例代碼的文章就介紹到這了,更多相關(guān)Java自定義重試內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Security 構(gòu)建rest服務(wù)實現(xiàn)rememberme 記住我功能
這篇文章主要介紹了Spring Security 構(gòu)建rest服務(wù)實現(xiàn)rememberme 記住我功能,需要的朋友可以參考下2018-03-03
Java數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)之樹
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)之樹,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java數(shù)據(jù)結(jié)構(gòu)的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-05-05
EL表達(dá)式的隱式對象_動力節(jié)點Java學(xué)院整理
這篇文章主要介紹了EL表達(dá)式的隱式對象,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07
idea環(huán)境下Maven無法正常下載pom中配置的包問題
這篇文章主要介紹了idea環(huán)境下Maven無法正常下載pom中配置的包的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06
Java利用Spire.XLS for Java自動化設(shè)置Excel的文檔屬性
一個專業(yè)的 Excel 文件,其文檔屬性往往能大大提升文件的可管理性和可檢索性,下面我們就來看看Java如何使用Spire.XLS for Java實現(xiàn)自動化設(shè)置Excel的文檔屬性吧2025-12-12

