
spring retry 1.3.x Fix mit Nischen-Toolkit für CVE-2026-41710
Dieses Projekt bietet deklarative Retry-Unterstützung für Spring-Anwendungen. Es wird in Spring Batch, Spring Integration und anderen verwendet. Imperatives Retry wird ebenfalls für die explizite Verwendung unterstützt.
Die Version fixiert spring-retry mit 2.0.13 für Java 8 und Spring 4 oder Spring 5. Weitere Informationen finden Sie in der offiziellen Spring 2.0.13-Version.
Dieser Abschnitt bietet eine kurze Einführung in die ersten Schritte mit Spring Retry. Er enthält ein deklaratives Beispiel und ein imperatives Beispiel.
Das folgende Beispiel zeigt, wie Spring Retry im deklarativen Stil verwendet wird:
@Configuration
@EnableRetry
public class Application {
@Bean
public Service service() {
return new Service();
}
}
@Service
class Service {
@Retryable(RemoteAccessException.class)
public void service() {
// ... do something
}
@Recover
public void recover(RemoteAccessException e) {
// ... panic
}
}
Dieses Beispiel ruft die Methode service auf und versucht bei einem Fehlschlag mit einer RemoteAccessException erneut (standardmäßig bis zu dreimal) und versucht anschließend die Methode recover, falls dies erfolglos bleibt.
In den Attributen der Annotation @Retryable gibt es verschiedene Optionen zum Ein- und Ausschließen von Ausnahmetypen, zur Begrenzung der Anzahl der Wiederholungsversuche und zur Festlegung der Backoff-Richtlinie.
Der deklarative Ansatz zur Anwendung der Wiederholungsbehandlung mithilfe der zuvor gezeigten Annotation @Retryable hat eine zusätzliche
Laufzeitabhängigkeit von AOP-Klassen. Einzelheiten zur Auflösung dieser Abhängigkeit in Ihrem Projekt finden Sie im
Abschnitt 'Java Configuration for Retry Proxies'.
Das folgende Beispiel zeigt, wie Spring Retry im imperativen Stil verwendet wird (verfügbar seit Version 1.3):
RetryTemplate template = RetryTemplate.builder()
.maxAttempts(3)
.fixedBackoff(1000)
.retryOn(RemoteAccessException.class)
.build();
template.execute(ctx -> {
// ... do something
});
Für Versionen vor 1.3 siehe die Beispiele im Abschnitt RetryTemplate.
Spring Retry erfordert Java 1.7 und Maven 3.0.5 (oder höher). Zum Erstellen führen Sie den folgenden Maven-Befehl aus:
$ mvn install
Dieser Abschnitt behandelt die Funktionen von Spring Retry und zeigt, wie dessen API verwendet wird.
RetryTemplateUm die Verarbeitung robuster und weniger fehleranfällig zu machen, ist es manchmal hilfreich,
eine fehlgeschlagene Operation automatisch erneut zu versuchen, falls sie bei einem nachfolgenden Versuch erfolgreich sein könnte.
Fehler, die für diese Art der Behandlung anfällig sind, sind vorübergehender Natur. Zum
Beispiel kann ein Remote-Aufruf an einen Webdienst oder einen RMI-Dienst, der aufgrund einer Netzwerkstörung
oder einer DeadLockLoserException bei einer Datenbankaktualisierung fehlschlägt, sich nach einer
kurzen Wartezeit von selbst auflösen. Um den erneuten Versuch solcher Operationen zu automatisieren, verfügt Spring Retry über die
Strategie RetryOperations. Die Definition der Schnittstelle RetryOperations folgt:
public interface RetryOperations {
<T> T execute(RetryCallback<T> retryCallback) throws Exception;
<T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback)
throws Exception;
<T> T execute(RetryCallback<T> retryCallback, RetryState retryState)
throws Exception, ExhaustedRetryException;
<T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback,
RetryState retryState) throws Exception;
}
Der Basis-Callback ist eine einfache Schnittstelle, mit der Sie eine Geschäftslogik einfügen können, die wiederholt werden soll:
public interface RetryCallback<T> {
T doWithRetry(RetryContext context) throws Throwable;
}
Der Callback wird versucht, und wenn er fehlschlägt (indem er eine Exception auslöst), wird er erneut versucht, bis er entweder erfolgreich ist oder die Implementierung beschließt, abzubrechen. Es gibt eine Reihe überladener execute-Methoden in der RetryOperations-Schnittstelle, um verschiedene Anwendungsfälle für die Wiederherstellung zu behandeln, wenn alle Wiederholungsversuche erschöpft sind, und um den Wiederholungszustand zu behandeln, der es Clients und Implementierungen ermöglicht, Informationen zwischen Aufrufen zu speichern (mehr dazu später).
Die einfachste Allzweck-Implementierung von RetryOperations ist RetryTemplate.
Das folgende Beispiel zeigt, wie man sie verwendet:
RetryTemplate template = new RetryTemplate();
TimeoutRetryPolicy policy = new TimeoutRetryPolicy();
policy.setTimeout(30000L);
template.setRetryPolicy(policy);
Foo result = template.execute(new RetryCallback<Foo>() {
public Foo doWithRetry(RetryContext context) {
// Do stuff that might fail, e.g. webservice operation
return result;
}
});
Im vorangehenden Beispiel führen wir einen Webdienst-Aufruf aus und geben das Ergebnis an den Benutzer zurück. Wenn dieser Aufruf fehlschlägt, wird er wiederholt, bis ein Timeout erreicht ist.
Seit Version 1.3 ist auch die fluente Konfiguration von RetryTemplate verfügbar, wie folgt:
RetryTemplate.builder()
.maxAttempts(10)
.exponentialBackoff(100, 2, 10000)
.retryOn(IOException.class)
.traversingCauses()
.build();
RetryTemplate.builder()
.fixedBackoff(10)
.withinMillis(3000)
.build();
RetryTemplate.builder()
.infiniteRetry()
.retryOn(IOException.class)
.uniformRandomBackoff(1000, 3000)
.build();
RetryContextDer Methodenparameter für den RetryCallback ist ein RetryContext. Viele Callbacks ignorieren
den Kontext. Bei Bedarf können Sie ihn jedoch als Attributbehälter verwenden, um Daten für
die Dauer der Iteration zu speichern.
Ein RetryContext hat einen übergeordneten Kontext, wenn im selben
Thread ein verschachtelter Retry läuft. Der übergeordnete Kontext ist gelegentlich nützlich, um Daten zu speichern, die zwischen
Aufrufen von execute geteilt werden müssen.
RecoveryCallbackWenn ein Retry erschöpft ist, kann RetryOperations die Kontrolle an einen anderen
Callback übergeben: RecoveryCallback. Um diese Funktion zu nutzen, können Clients die Callbacks
gemeinsam an dieselbe Methode übergeben, wie das folgende Beispiel zeigt:
Foo foo = template.execute(new RetryCallback<Foo>() {
public Foo doWithRetry(RetryContext context) {
// business logic here
},
new RecoveryCallback<Foo>() {
Foo recover(RetryContext context) throws Exception {
// recover logic here
}
});
Wenn die Geschäftslogik nicht erfolgreich ist, bevor die Vorlage beschließt, abzubrechen, erhält der Client die Möglichkeit, über den Recovery-Callback eine alternative Verarbeitung durchzuführen.