Vejledning til Spring Retry

1. Oversigt

Spring Retry giver mulighed for automatisk at genopkalde en mislykket operation. Dette er nyttigt, hvor fejlene kan være forbigående (som en kortvarig netværksfejl).

I denne vejledning ser vi de forskellige måder at bruge Spring Retry på: annoteringer, Prøv igen skabelonog tilbagekald.

2. Maven-afhængigheder

Lad os begynde med tilføje forsøg igen afhængighed af vores pom.xml fil:

 org.springframework.retry spring-retry 1.2.5.RELEASE 

Vi er også nødt til at tilføje Spring AOP til vores projekt:

 org.springframework fjederaspekter 5.2.8.RELEASE 

Se på Maven Central for de nyeste versioner af afhængighed af fjederforsøg og fjederaspekter.

3. Aktivering af Spring Retry

For at aktivere Spring Retry i en applikation, vi skal tilføje @EnableRetry kommentar til vores @Konfiguration klasse:

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

4. Brug af Spring Retry

4.1. @Retryable Uden opsving

For at tilføje forsøgsfunktionalitet til metoder kan vi bruge @Retryable kommentar:

@Service offentlig grænseflade MyService {@Retryable (værdi = RuntimeException.class) ugyldig retryService (streng SQL); }

I dette eksempel forsøges det at prøve igen, når en RuntimeException kastes.

Om @Retryable'S standardadfærd, forsøget kan ske op til tre gange med en forsinkelse på et sekund imellem forsøg igen.

4.2. @Retryable og @Gendanne

Lad os nu tilføje en gendannelsesmetode ved hjælp af @Gendanne kommentar:

@Service offentlig grænseflade MyService {@Retryable (værdi = SQLException.class) ugyldig retryServiceWithRecovery (streng sql) kaster SQLException; @Recover ugyldig gendannelse (SQLException e, String sql); }

I dette eksempel forsøges det at prøve igen, når en SQLException kastes.Det @Gendanne annotation definerer en separat gendannelsesmetode, når en @Retryable metoden mislykkes med en specificeret undtagelse.

Derfor, hvis retryServiceWithRecovery metoden fortsætter med at smide en SqlException efter 3 forsøg, den gendanne() metode kaldes.

Gendannelsesbehandleren skal have den første parameter af typen Kan kastes (valgfrit) og samme returtype.Følgende argumenter udfyldes fra argumentlisten for den mislykkede metode i samme rækkefølge.

4.3. Tilpasning @ Genforsøgelig Opførsel

For at tilpasse et forsøgs adfærd vi kan bruge parametrene maxAttfors og gå væk:

@Service offentlig grænseflade MyService {@Retryable (værdi = SQLException.class, maxAttempt = 2, backoff = @Backoff (forsinkelse = 100)) ugyldig retryServiceWithCustomization (streng sql) kaster SQLException; }

I eksemplet ovenfor vil der være op til 2 forsøg og en forsinkelse på 100 millisekunder.

4.4. Brug af Spring Properties

Vi kan også bruge egenskaber i @Retryable kommentar.

For at demonstrere dette, vi ser, hvordan man eksternaliserer værdierne for forsinke og maxAttfors ind i en egenskabsfil.

Lad os først definere egenskaberne i en fil, der hedder prøv igenConfig.ejendomme:

retry.maxAttempt = 2 forsøg.maxDelay = 100

Vi instruerer derefter vores @Konfiguration klasse for at indlæse denne fil:

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

Langt om længe, vi er i stand til at indsprøjte værdierne af retry.maxAttempts og prøv igen.maxDelay i vores @Retryable definition:

@Service offentlig grænseflade MyService {@Retryable (værdi = SQLException.class, maxAttemptExpression = "$ {retry.maxAttempt}", backoff = @Backoff (delayExpression = "$ {retry.maxDelay}")) ​​ugyldig retryServiceWithExternalizedConfiguration (String sql) throws SQLException; }

Bemærk, at vi bruger nu maxAttemptExpression og delayExpression i stedet for maxAttfors og forsinke.

5. Prøv igen skabelon

5.1 Prøv igen

Spring Retry giver Prøv igen interface, der leverer et sæt udføre () metoder:

offentlig grænseflade RetryOperations {T execute (RetryCallback retryCallback) kaster Undtagelse; ...}

Det RetryCallback som er en parameter for udføre () er en grænseflade, der tillader indsættelse af forretningslogik, der skal genprøves ved fiasko:

offentlig grænseflade RetryCallback {T doWithRetry (RetryContext context) kaster Throwable; }

5.2. Prøv igen skabelon Konfiguration

Det Prøv igen skabelon er en implementering af Prøv igen. Lad os konfigurere en Prøv igen skabelon bønne i vores @Konfiguration klasse:

@Configuration public class AppConfig {// ... @Bean public RetryTemplate retryTemplate () {RetryTemplate retryTemplate = new RetryTemplate (); FixedBackOffPolicy fixedBackOffPolicy = ny FixedBackOffPolicy (); fixedBackOffPolicy.setBackOffPeriod (2000l); retryTemplate.setBackOffPolicy (fixedBackOffPolicy); SimpleRetryPolicy retryPolicy = ny SimpleRetryPolicy (); retryPolicy.setMaxAttrors (2); retryTemplate.setRetryPolicy (retryPolicy); returner retryTemplate; }} 

Det Prøv igen bestemmer, hvornår en operation skal prøves igen.

EN SimpleRetryPolicy bruges til at prøve et fast antal gange igen. På den anden side er BackOffPolicy bruges til at kontrollere backoff mellem forsøg på ny forsøg.

Endelig a FixedBackOffPolicy pauser i en fast periode, inden du fortsætter.

5.3. Bruger Prøv igen skabelon

For at køre kode med forsøgshåndtering kan vi kalde r etryTemplate.execute () metode:

retryTemplate.execute (ny RetryCallback () {@ Override offentlig ugyldig doWithRetry (RetryContext arg0) {myService.templateRetryService (); ...}});

I stedet for en anonym klasse kan vi bruge et lambda-udtryk som følger:

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

6. Lyttere

Lyttere giver yderligere tilbagekald ved forsøg. Vi kan bruge disse til forskellige tværgående bekymringer på tværs af forskellige forsøg.

6.1. Tilføjelse af tilbagekald

Tilbagekaldene findes i a Prøv igenListener grænseflade:

offentlig klasse DefaultListenerSupport udvider RetryListenerSupport {@Override public void close (RetryContext context, RetryCallback callback, Throwable throwable) {logger.info ("onClose); ... super.close (context, callback, throwable);} @Override public void onError (RetryContext-kontekst, 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, tilbagekald); }}

Det åben og tæt tilbagekald kommer før og efter hele forsøget igen, mens onError gælder for individet RetryCallback opkald.

6.2. Registrering af lytteren

Dernæst registrerer vi vores lytter (DefaultListenerSupport) til vores Prøv igen skabelon bønne:

@Configuration public class AppConfig {... @Bean public RetryTemplate retryTemplate () {RetryTemplate retryTemplate = new RetryTemplate (); ... retryTemplate.registerListener (ny DefaultListenerSupport ()); returner retryTemplate; }}

7. Test af resultaterne

For at afslutte vores eksempel, lad os kontrollere resultaterne:

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

Som vi kan se fra testlogfiler, er Prøv igen skabelon og Prøv igenListener er korrekt konfigureret:

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 i method templateRetryService () 2020-01-09 20 : 04: 12 [main] INFO obsDefaultListenerSupport - onError 2020-01-09 20:04:12 [main] INFO obsDefaultListenerSupport - onClose

8. Konklusion

I denne artikel har vi set, hvordan du bruger Spring Retry ved hjælp af annoteringer, the Prøv igen, og tilbagekald lyttere.

Kildekoden til eksemplerne er tilgængelig på GitHub.