在springboot中,可以引入RetryTemplate的start包快速方便的使用。spring的项目就没那么方便了,这里针对spring项目对RetryTemplate做了简单的封装,抽象化处理。使得通用性更强。
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
package com.smy.tts.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.retry.RecoveryCallback;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.Callable;
/**
* 重试次数工具类
*
* @author youlu
* @ClassName RetryUtil
* @Date 2022/10/14 17:48
* @Version V1.0
**/
@Slf4j
@Component
public class RetryUtil {
/**
*功能描述
* @author youlu
* @date 2022/10/17 10:28
* @param retryCount 重试次数
* @param action 重试的方法
* @param desc 日志描述(用于打印成功or失败的日志)
* @return V
*/
public <V> V doRetry(int retryCount, Callable<V> action, String desc) {
RetryTemplate oRetryTemplate = new RetryTemplate();
SimpleRetryPolicy oRetryPolicy = new SimpleRetryPolicy();
oRetryPolicy.setMaxAttempts(retryCount);// 重试次数
oRetryTemplate.setRetryPolicy(oRetryPolicy);
try {
// obj为doWithRetry的返回结果,可以为任意类型
V obj = oRetryTemplate.execute(new RetryCallback<V, Exception>() {
@Override
public V doWithRetry(RetryContext context) throws Exception {// 开始重试
V v = action.call();
//log.info("{}成功", desc);
return v;
}
}, new RecoveryCallback<V>() {
@Override
public V recover(RetryContext context) throws Exception { // 重试多次后都失败了,可以考虑序列化至硬盘,发消息提醒...
log.error("{}重试:{}次失败,原因e:{}!", desc, retryCount, context.getLastThrowable());
return null;
}
});
return obj;
} catch (Exception e) {
log.error("执行{}出现异常e:{}", desc, e);
}
return null;
}
}