问题场景:
在项目中存在一些接口调用量比较巨大,超时获取其他异常情况频率比较高。且处理线上Case这些数据又比较重要。在业务方无法保证数据请求的准确性的情况下。要判断其在空或者抛出异常情况下,对接口多次请求,保证数据一定要请求成功。
原本简单实现方式:
for (int count = 0; count < 3; count++) {
Map<String, String> tmp = 调用请求方法;
if (tmp != null) {
result = tmp;
break;
}
}
从上面方法可以看出,如果有其他的方法也出现类似情况,简单实现方法还是采用这种for循环的方式,实现重复代码,建立for循环代码。
推荐方法:可以单独建立一个类,该类专门用来实现循环调用情况。将实现方法封装成一个类进行调用实现:
public class RetryService {
private static final Logger LOGGER = LoggerFactory.getLogger(RetryService.class);
/**
* 重复次数
*/
private static final Integer TIMES = 3;
/**
* 为NUll情况下重复调用
* @param callable
* @param <T>
* @return
*/
public static <T> T retryGetForNull(Callable<T> callable) {
T object = null;
for (int i = 0; i < TIMES; i++) {
try {
object = callable.call();
if (object != null) {
return object;
}
} catch (Exception e) {
LOGGER.info("多次查询(null情况):", e);
}
}
return object;
}
/**
* 抛异常情况下重复调用
* @param callable
* @param <T>
* @return
*/
public static <T> T retryGetForException(Callable<T> callable) {
T object = null;
for (int i = 0; i < TIMES; i++) {
try {
return callable.call();
} catch (Exception e) {
LOGGER.info("多次查询(异常情况):", e);
}
}
return object;
}
}
在调用该方法时候采用:
result = RetryService.retryGetForNull(() -> 该实现方法);
好处:可以不用过多的采用重复代码,实现重复的功能。这仅仅是简单实现重复调用的情况下时候,在很多其他的业务场景下也可以采用类似方法,避免出现过多的重复代码。