Vodič za proljetni pokušaj
1. Pregled
Spring Retry pruža mogućnost automatskog ponovnog poziva na neuspjelu operaciju. Ovo je korisno ako pogreške mogu biti prolazne (poput trenutnog kvara na mreži).
U ovom uputstvu vidjet ćemo razne načine korištenja Spring Retry: napomene, RetryTemplatei povratne pozive.
2. Ovisnosti Mavena
Krenimo od dodavanjem proljetni-ponovni pokušaj ovisnost o našoj pom.xml datoteka:
org.springframework.ponovni pokušaj opruge-ponovni pokušaj 1.2.5.OBUSTAVLJANJE
U naš projekt također trebamo dodati Spring AOP:
org.springframework spring-aspekti 5.2.8.OBUSTAŽENJE
U Maven Centralu potražite najnovije verzije ovisnosti o opružnom ponovnom pokušaju i proljetnim aspektima.
3. Omogućavanje proljetnog ponovnog pokušaja
Da biste omogućili proljetni pokušaj u aplikaciji, moramo dodati @EnableRetry bilješka našem @Konfiguracija razred:
@Configuration @EnableRetry javna klasa AppConfig {...}
4. Korištenje proljetnog ponovnog pokušaja
4.1. @Retryable Bez oporavka
Da bismo metodama dodali funkcionalnost ponovnog pokušaja, možemo koristiti @Retryable napomena:
@Service javno sučelje MyService {@Retryable (value = RuntimeException.class) void retryService (String sql); }
U ovom se primjeru pokušava ponoviti pokušaj kada a RuntimeException baca se.
Po @RetryableZadano ponašanje, ponovni pokušaj može se dogoditi do tri puta, s odgodom od jedne sekunde između ponovljenih pokušaja.
4.2. @Retryable i @Oporavak
Dodajmo sada metodu oporavka pomoću @Oporavak napomena:
@Service javno sučelje MyService {@Retryable (value = SQLException.class) void retryServiceWithRecovery (String sql) baca SQLException; @Recover void recovery (SQLException e, String sql); }
U ovom se primjeru pokušava ponoviti pokušaj kada se SQLException baca se.The @Oporavak napomena definira zasebnu metodu oporavka kada a @Retryable metoda ne uspije s navedenom iznimkom.
Slijedom toga, ako je retryServiceWithRecovery metoda nastavlja bacati a SqlException nakon 3 pokušaja, oporavak() pozvat će se metoda.
Rukovatelj oporavkom trebao bi imati prvi parametar tipa Bacljivo (nije obavezno) i isti tip povrata.Sljedeći se argumenti popunjavaju s popisa argumenata neuspjele metode istim redoslijedom.
4.3. Prilagođavanje @ Retryable's Ponašanje
Da biste prilagodili ponašanje ponovnog pokušaja, možemo koristiti parametre maxAttempts i odstupi:
@Service javno sučelje MyService {@Retryable (value = SQLException.class, maxAttempts = 2, backoff = @Backoff (delay = 100)) void retryServiceWithCustomization (String sql) baca SQLException; }
U gornjem primjeru bit će do 2 pokušaja i kašnjenje od 100 milisekundi.
4.4. Korištenje svojstava opruge
Također možemo koristiti svojstva u @Retryable bilješka.
Da bi to demonstrirali, vidjet ćemo kako eksternalizirati vrijednosti odgoditi i maxAttempts u datoteku svojstava.
Prvo, definirajmo svojstva u datoteci koja se zove ponovitiConfig.Svojstva:
retry.maxAttempts = 2 retry.maxDelay = 100
Zatim upućujemo svoje @Konfiguracija razred za učitavanje ove datoteke:
// ... @PropertySource ("classpath: retryConfig.properties") javna klasa AppConfig {...}
Konačno, možemo ubrizgati vrijednosti pokušaj ponovnog pokušaja. max i ponoviti.maxDelay u našem @Retryable definicija:
Javno sučelje @Service MyService {@Retryable (value = SQLException.class, maxAttemptsExpression = "$ {retry.maxAttempts}", backoff = @Backoff (delayExpression = "$ {retry.maxDelay}")) void retryServiceWithExternalized StonWf SQLException; }
Imajte na umu da sada koristimo maxAttemptsExpression i delayExpression umjesto maxAttempts i odgoditi.
5. RetryTemplate
5.1 RetryOperations
Spring Retry nudi RetryOperations sučelje koje pruža skup izvršiti() metode:
javno sučelje RetryOperations {T izvršavanje (RetryCallback retryCallback) baca iznimku; ...}
The RetryCallback što je parametar izvršiti() je sučelje koje omogućuje umetanje poslovne logike koju treba pokušati ponovno nakon neuspjeha:
javno sučelje RetryCallback {T doWithRetry (kontekst RetryContext) baca Throwable; }
5.2. RetryTemplate Konfiguracija
The RetryTemplate je provedba RetryOperations. Konfigurirajmo a RetryTemplate grah u našem @Konfiguracija razred:
@Configuration javna klasa AppConfig {// ... @Bean public RetryTemplate retryTemplate () {RetryTemplate retryTemplate = new RetryTemplate (); FixedBackOffPolicy fixedBackOffPolicy = novo FixedBackOffPolicy (); fixedBackOffPolicy.setBackOffPeriod (2000l); retryTemplate.setBackOffPolicy (fixedBackOffPolicy); SimpleRetryPolicy retryPolicy = novo SimpleRetryPolicy (); retryPolicy.setMaxAttempts (2); retryTemplate.setRetryPolicy (retryPolicy); vratiti retryTemplate; }}
The RetryPolicy određuje kada operaciju treba ponoviti.
A SimpleRetryPolicy koristi se za ponovni pokušaj određenog broja puta. S druge strane, BackOffPolicy koristi se za kontrolu nadoknade između pokušaja ponovnog pokušaja.
Konačno, a FixedBackOffPolicy zastaje na određeno vrijeme prije nastavka.
5.3. Koristiti RetryTemplate
Za pokretanje koda s ponovnim rukovanjem možemo nazvati r etryTemplate.execute () metoda: Umjesto anonimne klase, možemo koristiti lambda izraz kako slijedi: Slušatelji pružaju dodatne povratne pozive nakon ponovnih pokušaja. Možemo ih koristiti za razne presječne probleme u različitim pokušajima. Povratni pozivi navedeni su u a RetryListener sučelje: The otvorena i Zatvoriti povratni pozivi dolaze prije i nakon cijelog ponovnog pokušaja, dok onError odnosi se na pojedinca RetryCallback poziva. Dalje, registriramo našeg slušatelja (Podržana podrška za slušatelje) našem RetryTemplate grah: Za kraj našeg primjera, provjerimo rezultate: Kao što možemo vidjeti iz dnevnika ispitivanja, RetryTemplate i RetryListener su pravilno konfigurirani: U ovom smo članku vidjeli kako se koristi Spring Retry koristeći napomene, RetryTemplate, i slušatelji povratnih poziva. Izvorni kod za primjere dostupan je na GitHubu.retryTemplate.execute (new RetryCallback () {@Override public Void doWithRetry (RetryContext arg0) {myService.templateRetryService (); ...}});
retryTemplate.execute (arg0 -> {myService.templateRetryService (); vrati nulu;});
6. Slušatelji
6.1. Dodavanje povratnih poziva
javna klasa DefaultListenerSupport proširuje RetryListenerSupport {@Override public void close (RetryContext context, RetryCallback callback, Throwable throwwable) {logger.info ("onClose); ... super.close (context, callback, bacanje);} @Override public void onError (RetryContext context, RetryCallback callback, Throwable throwable) {logger.info ("onError"); ... super.onError (context, callback, bacanje);} @Override public boolean open (RetryContext context, RetryCallback callback) {logger. info ("onOpen); ... povratak super.open (kontekst, povratni poziv); }}
6.2. Registriranje slušatelja
@Configuration javna klasa AppConfig {... @Bean public RetryTemplate retryTemplate () {RetryTemplate retryTemplate = new RetryTemplate (); ... retryTemplate.registerListener (novi DefaultListenerSupport ()); vratiti retryTemplate; }}
7. Testiranje rezultata
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (classes = AppConfig.class, loader = AnnotationConfigContextLoader.class) javna klasa SpringRetryIntegrationTest {@Autowired private MyService myService; @Autowired private RetryTemplate retryTemplate; @Test (očekuje se = RuntimeException.class) javna praznina givenTemplateRetryService_whenCallWithException_thenRetry () {retryTemplate.execute (arg0 -> {myService.templateRetryService (); return null;}); }}
2020-01-09 20:04:10 [glavna] INFO obsDefaultListenerSupport - onOpen 2020-01-09 20:04:10 [glavna] INFO o.baeldung.springretry.MyServiceImpl - baci RuntimeException u metodu templateRetryService () 2020-01 -09 20:04:10 [glavna] INFO obsDefaultListenerSupport - onError 2020-01-09 20:04:12 [glavna] INFO o.baeldung.springretry.MyServiceImpl - baci RuntimeException u metodu templateRetryService () 2020-01-09 20 : 04: 12 [glavna] INFO obsDefaultListenerSupport - onError 2020-01-09 20:04:12 [glavna] INFO obsDefaultListenerSupport - onClose
8. Zaključak