@Retryable
(и базовый RetryTemplate
) основаны исключительно на исключениях.
Вы можете создать подкласс RetryTemplate
, переопределив doExecute()
для проверки возвращаемого значения.
Вероятно, вам придется реплицировать большую часть кода в методе; на самом деле он не предназначен для переопределения только вызова retryCallback.doWithRetry()
.
Вы можете использовать пользовательский RetryTemplate
в RetryOperationsInterceptor
(указанный в @Retryable
в свойстве interceptor
).
ИЗМЕНИТЬ
Текущий код RetryTemplate
выглядит так...
while (canRetry(retryPolicy, context) && !context.isExhaustedOnly()) {
try {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Retry: count=" + context.getRetryCount());
}
// Reset the last exception, so if we are successful
// the close interceptors will not think we failed...
lastException = null;
return retryCallback.doWithRetry(context);
}
catch (Throwable e) {
lastException = e;
try {
registerThrowable(retryPolicy, state, context, e);
}
catch (Exception ex) {
throw new TerminatedRetryException("Could not register throwable",
ex);
}
finally {
doOnErrorInterceptors(retryCallback, context, e);
}
...
}
Вам нужно изменить его на что-то вроде...
while (canRetry(retryPolicy, context) && !context.isExhaustedOnly()) {
try {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Retry: count=" + context.getRetryCount());
}
// Reset the last exception, so if we are successful
// the close interceptors will not think we failed...
lastException = null;
T result = retryCallback.doWithRetry(context);
if (((Optional<String>) result).get() == null) {
try {
registerThrowable(retryPolicy, state, context, someDummyException);
}
catch (Exception ex) {
throw new TerminatedRetryException("Could not register throwable",
ex);
}
finally {
doOnErrorInterceptors(retryCallback, context, e);
}
...
}
else {
return result;
}
}
catch (Throwable e) {
...
}
Где someDummyException
должен обмануть контекст, чтобы увеличить счетчик. Это может быть поле static
, только что созданное один раз.
person
Gary Russell
schedule
04.02.2019
Optional.orElseThrow(...)
? Логики много не напишешь... - person Turing85   schedule 04.02.2019Optional
в первую очередь? Я имею в виду, что поскольку@Retryable
работает с генерируемыми исключениями, вы вполне можете создать свое собственное исключение, генерировать его, если значение не получено, а затем повторить операцию. Таким образом, вы сэкономите время на написании собственной аннотации и тому подобного. - person akortex91   schedule 04.02.2019