Guide til Spring Retry

1. Oversikt

Spring Retry gir muligheten til å automatisk påkalle en mislykket operasjon. Dette er nyttig der feilene kan være forbigående (som en kortvarig nettverksfeil).

I denne opplæringen ser vi de forskjellige måtene å bruke Spring Retry på: kommentarer, Prøv på nyttog tilbakeringing.

2. Maven-avhengigheter

La oss begynne med legge til prøv på nytt avhengighet i vår pom.xml fil:

 org.springframework.retry spring-retry 1.2.5.RELEASE 

Vi må også legge til Spring AOP i prosjektet vårt:

 org.springframework våraspekter 5.2.8.RELEASE 

Ta en titt på Maven Central for de nyeste versjonene av avhengighet av vårforsøk og våraspekter.

3. Aktivere vårprøve på nytt

For å aktivere Spring Retry i et program, vi trenger å legge til @EnableRetry kommentar til vår @Konfigurasjon klasse:

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

4. Bruke Spring Retry

4.1. @Retryable Uten utvinning

For å legge til prøvefunksjonalitet på nytt, kan vi bruke @Retryable kommentar:

@Service offentlig grensesnitt MyService {@Retryable (verdi = RuntimeException.class) ugyldig retryService (streng sql); }

I dette eksemplet blir det forsøkt på nytt når en RuntimeException blir kastet.

Per @RetryableStandard oppførsel, forsøket kan skje opptil tre ganger, med en forsinkelse på ett sekund mellom prøvene igjen.

4.2. @Retryable og @Komme seg

La oss nå legge til en gjenopprettingsmetode ved hjelp av @Komme seg kommentar:

@Service offentlige grensesnitt MyService {@Retryable (verdi = SQLException.class) ugyldig retryServiceWithRecovery (streng sql) kaster SQLException; @Recover void recover (SQLException e, String sql); }

I dette eksemplet blir det forsøkt på nytt når en SQLException blir kastet.De @Komme seg kommentar definerer en egen gjenopprettingsmetode når en @Retryable metoden mislykkes med et spesifisert unntak.

Følgelig, hvis retryServiceWithRecovery metoden fortsetter å kaste a SqlException etter 3 forsøk, den komme seg() metoden vil bli kalt.

Gjenopprettingsbehandleren bør ha den første parameteren av typen Kastbar (valgfritt) og samme returtype.Følgende argumenter fylles ut fra argumentlisten til den mislykkede metoden i samme rekkefølge.

4.3. Tilpasse @ Retryable's Oppførsel

For å tilpasse atferd på nytt, vi kan bruke parametrene maxAttfors og gå vekk:

@Service offentlig grensesnitt MyService {@Retryable (verdi = SQLException.class, maxAttempt = 2, backoff = @Backoff (forsinkelse = 100)) ugyldig retryServiceWithCustomization (streng sql) kaster SQLException; }

I eksemplet ovenfor vil det være opptil 2 forsøk og en forsinkelse på 100 millisekunder.

4.4. Bruke Spring Properties

Vi kan også bruke egenskaper i @Retryable kommentar.

For å demonstrere dette, vi får se hvordan vi kan eksternalisere verdiene til forsinkelse og maxAttfors inn i en eiendomsfil.

La oss først definere egenskapene i en fil som heter prøv på nyttConfig.eiendommer:

retry.maxAttempt = 2 prøv på nytt.maxDelay = 100

Vi instruerer deretter vår @Konfigurasjon klasse for å laste inn denne filen:

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

Endelig, vi kan injisere verdiene av prøv på nytt.maxAttempts og prøv på nytt.maxDelay i vår @Retryable definisjon:

@Service offentlige grensesnitt MyService {@Retryable (verdi = SQLException.class, maxAttemptExpression = "$ {retry.maxAttempt}", backoff = @Backoff (delayExpression = "$ {retry.maxDelay}")) ​​ugyldig retryServiceWithExternalizedConfiguration (String sql) throws SQLException; }

Vær oppmerksom på at vi bruker nå maxAttemptExpression og delayExpression i stedet for maxAttfors og forsinkelse.

5. Prøv på nytt

5.1 Prøv på nytt

Spring Retry gir Prøv på nytt grensesnitt som leverer et sett med henrette() metoder:

offentlig grensesnitt RetryOperations {T execute (RetryCallback retryCallback) kaster Unntak; ...}

De Prøv på nytt som er en parameter for henrette() er et grensesnitt som tillater innsetting av forretningslogikk som må prøves på nytt ved feil:

offentlig grensesnitt RetryCallback {T doWithRetry (RetryContext context) kaster Throwable; }

5.2. Prøv på nytt Konfigurasjon

De Prøv på nytt er en implementering av Prøv på nytt. La oss konfigurere en Prøv på nytt bønne i vår @Konfigurasjon klasse:

@Configuration public class AppConfig {// ... @Bean public RetryTemplate retryTemplate () {RetryTemplate retryTemplate = new RetryTemplate (); FixedBackOffPolicy fixedBackOffPolicy = ny FixedBackOffPolicy (); fixedBackOffPolicy.setBackOffPeriod (2000l); prøv på nytt Template.setBackOffPolicy (fixedBackOffPolicy); SimpleRetryPolicy retryPolicy = ny SimpleRetryPolicy (); retryPolicy.setMaxAttrors (2); retryTemplate.setRetryPolicy (retryPolicy); return retryTemplate; }} 

De Prøv på nytt bestemmer når en operasjon skal prøves på nytt.

EN SimpleRetryPolicy brukes til å prøve et fast antall ganger på nytt. På den annen side, den BackOffPolicy brukes til å kontrollere tilbakeslag mellom forsøk på nytt.

Til slutt, a FixedBackOffPolicy pauser i en bestemt periode før du fortsetter.

5.3. Bruker Prøv på nytt

For å kjøre kode med håndtering på nytt kan vi ringe r etryTemplate.execute () metode:

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

I stedet for en anonym klasse kan vi bruke et lambdauttrykk som følger:

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

6. Lyttere

Lyttere gir ytterligere tilbakeringinger ved forsøk. Vi kan bruke disse til ulike bekymringer på tvers av forskjellige forsøk.

6.1. Legge til tilbakeringinger

Tilbakeringingene er gitt i a Prøv på nytt grensesnitt:

offentlig klasse DefaultListenerSupport utvider RetryListenerSupport {@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); ... returner super.open (kontekst, tilbakeringing); }}

De åpen og Lukk tilbakeringinger kommer før og etter hele forsøket, mens onError gjelder individet Prøv på nytt ringer.

6.2. Registrere lytteren

Deretter registrerer vi lytteren vår (DefaultListenerSupport) til vår Prøv på nytt bønne:

@Configuration public class AppConfig {... @Bean public RetryTemplate retryTemplate () {RetryTemplate retryTemplate = new RetryTemplate (); ... prøv på nytt Template.registerListener (ny DefaultListenerSupport ()); return retryTemplate; }}

7. Testing av resultatene

For å avslutte eksemplet vårt, la oss verifisere resultatene:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (classes = AppConfig.class, loader = AnnotationConfigContextLoader.class) public class SpringRetryIntegrationTest {@Autowired private MyService myService; @Autowired private RetryTemplate retryTemplate; @Test (forventet = RuntimeException.class) offentlig ugyldig givenTemplateRetryService_whenCallWithException_thenRetry () {retryTemplate.execute (arg0 -> {myService.templateRetryService (); return null;}); }}

Som vi kan se fra testloggene, Prøv på nytt og Prøv på nytt er riktig konfigurert:

2020-01-09 20:04:10 [main] INFO obsDefaultListenerSupport - onOpen 2020-01-09 20:04:10 [main] INFO o.baeldung.springretry.MyServiceImpl - throw 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 - throw 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. Konklusjon

I denne artikkelen har vi sett hvordan du kan bruke Spring Retry ved å bruke merknader Prøv på nytt, og tilbakekallingslyttere.

Kildekoden for eksemplene er tilgjengelig på GitHub.