J'utilise compile 'org.springframework.retry:spring-retry:1.2.2.RELEASE'
avec Spring Boot 1.5.9.RELEASE
.
Configuré pour réessayer ma méthode et cela fonctionne bien:
@Retryable(value = { IOException.class }, maxAttempts = 5, backoff = @Backoff(delay = 500))
public void someMethod(){...}
Comment afficher un message spécifique lors d'une nouvelle tentative?
En parcourant le code, le org.springframework.retry.support.RetryTemplate
exécute la logique de nouvelle tentative pour réessayer les opérations. Ce modèle enregistre uniquement des éléments simples tels que:
o.s.retry.support.RetryTemplate : Retry: count=0
o.s.retry.support.RetryTemplate : Checking for rethrow: count=1
o.s.retry.support.RetryTemplate : Retry: count=1
o.s.retry.support.RetryTemplate : Checking for rethrow: count=2
o.s.retry.support.RetryTemplate : Retry: count=2
o.s.retry.support.RetryTemplate : Checking for rethrow: count=3
o.s.retry.support.RetryTemplate : Retry failed last attempt: count=3
Si vous souhaitez enregistrer l'exception spécifique, vous pouvez intercepter le journal d'exception et recommencer. Malheureusement, pour autant que je puisse voir, il n'y a aucun moyen d'enregistrer des messages personnalisés dans le cadre.
Une autre méthode serait d'occulter l'intercepteur réel responsable de l'invocation de votre méthode comme RetryOperationsInterceptor
, ce n'est cependant pas conseillé.
Vous pouvez enregistrer un RetryListener
:
@Bean
public List<RetryListener> retryListeners() {
Logger log = LoggerFactory.getLogger(getClass());
return Collections.singletonList(new RetryListener() {
@Override
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
// The 'context.name' attribute has not been set on the context yet. So we have to use reflection.
Field labelField = ReflectionUtils.findField(callback.getClass(), "val$label");
ReflectionUtils.makeAccessible(labelField);
String label = (String) ReflectionUtils.getField(labelField, callback);
log.trace("Starting retryable method {}", label);
return true;
}
@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
log.warn("Retryable method {} threw {}th exception {}",
context.getAttribute("context.name"), context.getRetryCount(), throwable.toString());
}
@Override
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
log.trace("Finished retryable method {}", context.getAttribute("context.name"));
}
});
Si vous n'avez pas besoin de vous connecter à partir des 3 points d'interception, vous pouvez remplacer RetryListenerSupport
à la place. Par exemple:
@Bean
public List<RetryListener> retryListeners() {
Logger log = LoggerFactory.getLogger(getClass());
return Collections.singletonList(new RetryListenerSupport() {
@Override
public <T, E extends Throwable> void onError(
RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
log.warn("Retryable method {} threw {}th exception {}",
context.getAttribute("context.name"),
context.getRetryCount(), throwable.toString());
}
});
}