Gids voor Spring Retry

1. Overzicht

Spring Retry biedt de mogelijkheid om een ​​mislukte bewerking automatisch opnieuw uit te voeren. Dit is handig wanneer de fouten van voorbijgaande aard kunnen zijn (zoals een tijdelijke netwerkstoring).

In deze zelfstudie zien we de verschillende manieren waarop u Spring Retry kunt gebruiken: annotaties, RetryTemplateen terugbellen.

2. Maven afhankelijkheden

Laten we beginnen met het toevoegen van de voorjaar opnieuw proberen afhankelijkheid van onze pom.xml het dossier:

 org.springframework.retry spring-retry 1.2.5.RELEASE 

We moeten ook Spring AOP aan ons project toevoegen:

 org.springframework lente-aspecten 5.2.8.RELEASE 

Bekijk Maven Central voor de nieuwste versies van de afhankelijkheden van lente-nieuwe pogingen en lente-aspecten.

3. Spring Retry inschakelen

Om Spring Retry in een applicatie in te schakelen, we moeten de @EnableRetry annotatie naar onze @Configuratie klasse:

@Configuration @EnableRetry openbare klasse AppConfig {...}

4. Spring Retry gebruiken

4.1. @Retryable Zonder herstel

Om functionaliteit voor opnieuw proberen aan methoden toe te voegen, kunnen we de @Retryable annotatie:

@Service openbare interface MyService {@Retryable (waarde = RuntimeException.class) void retryService (String sql); }

In dit voorbeeld wordt geprobeerd het opnieuw te proberen wanneer een RuntimeException wordt gegooid.

Per @Retryable‘Standaardgedrag, het opnieuw proberen kan tot drie keer gebeuren, met een vertraging van één seconde tussen het opnieuw proberen.

4.2. @Retryable en @Herstellen

Laten we nu een herstelmethode toevoegen met behulp van de @Herstellen annotatie:

@Service openbare interface MyService {@Retryable (waarde = SQLException.class) void retryServiceWithRecovery (String sql) gooit SQLException; @Recover ongeldig herstellen (SQLException e, String sql); }

In dit voorbeeld wordt geprobeerd het opnieuw te proberen wanneer een SQLException wordt gegooid.De @Herstellen annotatie definieert een afzonderlijke herstelmethode wanneer een @Retryable methode mislukt met een opgegeven uitzondering.

Als het retryServiceWithRecovery methode blijft een SqlException na 3 pogingen is de herstellen() methode wordt aangeroepen.

De herstelhandler moet de eerste parameter van het type hebben Gooibaar (optioneel) en hetzelfde retourtype.De volgende argumenten worden in dezelfde volgorde uit de lijst met argumenten van de mislukte methode ingevuld.

4.3. Aanpassen @ Opnieuw proberen Gedrag

Om het gedrag van een nieuwe poging aan te passen, we kunnen de parameters gebruiken maxAttempts en Donder op:

@Service openbare interface MyService {@Retryable (waarde = SQLException.class, maxAttempts = 2, backoff = @Backoff (vertraging = 100)) void retryServiceWithCustomization (String sql) gooit SQLException; }

In het bovenstaande voorbeeld zijn er maximaal 2 pogingen en een vertraging van 100 milliseconden.

4.4. Spring-eigenschappen gebruiken

We kunnen ook eigenschappen gebruiken in de @Retryable annotatie.

Om dit aan te tonen, we zullen zien hoe we de waarden van vertraging en maxAttempts in een eigenschappenbestand.

Laten we eerst de eigenschappen definiëren in een bestand met de naam retryConfig.eigendommen:

retry.maxAttempts = 2 retry.maxDelay = 100

We instrueren dan onze @Configuratie class om dit bestand te laden:

// ... @PropertySource ("classpath: retryConfig.properties") openbare klasse AppConfig {...}

Tenslotte, we kunnen de waarden van injecteren retry.maxAttempts en retry.maxDelay in onze @Retryable definitie:

@Service openbare interface MyService {@Retryable (waarde = SQLException.class, maxAttemptsExpression = "$ {retry.maxAttempts}", backoff = @Backoff (delayExpression = "$ {retry.maxDelay}")) ​​ongeldig retryServiceWithExternalizedConfiguration (String sql) SQLException; }

Houd er rekening mee dat we gebruiken nu maxAttemptsExpression en delayExpression in plaats van maxAttempts en vertraging.

5. RetryTemplate

5.1 Opnieuw proberen

Spring Retry biedt Opnieuw proberen interface die een set van uitvoeren () methoden:

openbare interface RetryOperations {T uitvoeren (RetryCallback retryCallback) genereert uitzondering; ...}

De Opnieuw proberen terug te bellen wat een parameter is van de uitvoeren () is een interface waarmee bedrijfslogica kan worden ingevoegd die opnieuw moet worden geprobeerd bij een storing:

openbare interface RetryCallback {T doWithRetry (RetryContext-context) gooit Throwable; }

5.2. RetryTemplate Configuratie

De RetryTemplate is een implementatie van de Opnieuw proberen. Laten we een RetryTemplate boon in onze @Configuratie klasse:

@Configuration openbare klasse AppConfig {// ... @Bean openbaar RetryTemplate retryTemplate () {RetryTemplate retryTemplate = nieuwe RetryTemplate (); FixedBackOffPolicy fixedBackOffPolicy = nieuwe FixedBackOffPolicy (); fixedBackOffPolicy.setBackOffPeriod (2000l); retryTemplate.setBackOffPolicy (fixedBackOffPolicy); SimpleRetryPolicy retryPolicy = nieuwe SimpleRetryPolicy (); retryPolicy.setMaxAttempts (2); retryTemplate.setRetryPolicy (retryPolicy); retry retryTemplate; }} 

De RetryPolicy bepaalt wanneer een bewerking opnieuw moet worden geprobeerd.

EEN SimpleRetryPolicy wordt gebruikt om een ​​vast aantal keren opnieuw te proberen. Aan de andere kant is het BackOffPolicy wordt gebruikt om uitstel tussen nieuwe pogingen te regelen.

Eindelijk een FixedBackOffPolicy pauzeert voor een vaste tijdsperiode alvorens verder te gaan.

5.3. De ... gebruiken RetryTemplate

Om code uit te voeren met het afhandelen van nieuwe pogingen, kunnen we de r aanroepen etryTemplate.execute () methode:

retryTemplate.execute (nieuwe RetryCallback () {@Override public Void doWithRetry (RetryContext arg0) {myService.templateRetryService (); ...}});

In plaats van een anonieme klasse kunnen we als volgt een lambda-uitdrukking gebruiken:

retryTemplate.execute (arg0 -> {myService.templateRetryService (); return null;}); 

6. Luisteraars

Listeners bieden extra callbacks bij nieuwe pogingen. We kunnen deze gebruiken voor verschillende transversale problemen bij verschillende nieuwe pogingen.

6.1. Terugbelopdrachten toevoegen

De callbacks worden geleverd in een RetryListener koppel:

public class DefaultListenerSupport breidt RetryListenerSupport uit {@Override public void close (RetryContext context, RetryCallback callback, Throwable throwable) {logger.info ("onClose); ... super.close (context, callback, throwable);} @Override public void onError (RetryContext context, RetryCallback callback, Throwable throwable) {logger.info ("onError"); ... super.onError (context, callback, throwable);} @Override public boolean open (RetryContext context, RetryCallback callback) {logger. info ("onOpen); ... return super.open (context, callback); }}

De Open en dichtbij callbacks komen voor en na de volledige nieuwe poging, while onError geldt voor het individu Opnieuw proberen terug te bellen oproepen.

6.2. De luisteraar registreren

Vervolgens registreren we onze luisteraar (DefaultListenerSupport) naar onze RetryTemplate Boon:

@Configuration openbare klasse AppConfig {... @Bean openbaar RetryTemplate retryTemplate () {RetryTemplate retryTemplate = nieuwe RetryTemplate (); ... retryTemplate.registerListener (nieuwe DefaultListenerSupport ()); retry retryTemplate; }}

7. Testen van de resultaten

Laten we om ons voorbeeld af te sluiten de resultaten verifiëren:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (classes = AppConfig.class, loader = AnnotationConfigContextLoader.class) openbare klasse SpringRetryIntegrationTest {@Autowired privé MyService myService; @Autowired privé RetryTemplate retryTemplate; @Test (verwacht = RuntimeException.class) public void givenTemplateRetryService_whenCallWithException_thenRetry () {retryTemplate.execute (arg0 -> {myService.templateRetryService (); return null;}); }}

Zoals we kunnen zien aan de hand van de testlogboeken, is het RetryTemplate en de RetryListener correct zijn geconfigureerd:

2020-01-09 20:04:10 [main] INFO obsDefaultListenerSupport - onOpen 2020-01-09 20:04:10 [main] INFO o.baeldung.springretry.MyServiceImpl - gooi RuntimeException in method templateRetryService () 2020-01 -09 20:04:10 [main] INFO obsDefaultListenerSupport - onError 2020-01-09 20:04:12 [main] INFO o.baeldung.springretry.MyServiceImpl - gooi RuntimeException in method templateRetryService () 2020-01-09 20 : 04: 12 [main] INFO obsDefaultListenerSupport - onError 2020-01-09 20:04:12 [main] INFO obsDefaultListenerSupport - onClose

8. Conclusie

In dit artikel hebben we gezien hoe u Spring Retry kunt gebruiken met annotaties, de Opnieuw proberen sjabloon, en callbacks luisteraars.

De broncode voor de voorbeelden is beschikbaar op GitHub.