Если вам требуется такая функциональность чаще, вы можете захотеть создать для этого собственную утилиту поддержки (которую вы также можете улучшить в зависимости от своих потребностей), например ::
public class Retry {
public static <T> T endlessTryCall(Callable<T> callable, Consumer<Exception> exceptionHandler) {
for(;;) try {
return callable.call();
} catch (Exception e) {
exceptionHandler.accept(e);
}
}
public static void endlessTryRun(Runnable runnable, Consumer<Exception> exceptionHandler) {
for(;;) try {
runnable.run();
return;
} catch (Exception e) {
exceptionHandler.accept(e);
}
}
}
Ваши функции могут выглядеть следующим образом:
private void fun1(int a){
Retry.endlessTryRun(() -> {
// the API calls
}, e -> refreshToken());
}
private int fun2(int a, String b){
return Retry.endlessTryCall(() -> {
// the API calls
return ...;
}, e -> refreshToken());
}
private void fun3(String a, long b, char c){
Retry.endlessTryRun(() -> {
// the API calls
}, e -> refreshToken());
}
Дополнительные улучшения могут заключаться в том, чтобы иметь что-то вроде tryCall(numberOfTrials, ...)
-функции или другую функцию, которая обрабатывает исключение так, как вам нужно. Демонстрируя последнее:
private void fun1(int a){
refreshTokenOnException(() -> {
// the API calls
});
}
private int fun2(int a, String b){
return refreshTokenOnException(() -> {
// the API calls
return ...;
});
}
private void fun3(String a, long b, char c){
refreshTokenOnException(() -> {
// the API calls
});
}
private <T> T refreshTokenOnException(Callable<T> callable) {
return Retry.endlessTryCall(callable, e -> refreshToken());
}
private void refreshTokenOnException(Runnable runnable) {
Retry.endlessTryRun(runnable, e -> refreshToken());
}
Преимущество наличия такой утилиты на месте, вероятно, сомнительно. Я думаю, что это немного более многословно относительно того, что сделано. Но опять же, нужно найти подходящие имена для него ... так что ... как всегда.