Master Spring Retry: Using @Retryable and @Recover for Robust Backend Retries
This guide explains how to use Spring Retry’s @Retryable and @Recover annotations in Spring Boot, covering dependency setup, enabling retries, annotating methods, configuring backoff policies, handling exhausted retries, and important precautions for reliable backend retry mechanisms.
Preface
In real work, retry is a common scenario, such as message sending failure, remote service call failure, or lock acquisition failure. These errors may be caused by network fluctuations; waiting and retrying can succeed. Usually try/catch or while loops are used, but they lack uniformity. Spring‑retry provides annotation‑based, non‑intrusive retry functionality.
What is @Retryable?
spring-retry is a utility module that helps handle retries in a standard way. All configuration is based on simple annotations.
Usage Steps
POM Dependency
<code><dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency></code>Enable @Retryable
<code>@EnableRetry
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}</code>Add @Retryable on Method
<code>import com.mail.elegant.service.TestRetryService;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import java.time.LocalTime;
@Service
public class TestRetryServiceImpl implements TestRetryService {
@Override
@Retryable(value = Exception.class, maxAttempts = 3,
backoff = @Backoff(delay = 2000, multiplier = 1.5))
public int test(int code) throws Exception {
System.out.println("test被调用,时间:" + LocalTime.now());
if (code == 0) {
throw new Exception("情况不对头!");
}
System.out.println("test被调用,情况对头了!");
return 200;
}
}</code>Explanation of annotation parameters:
value: retry only for the specified exception types.
include: same as
value; default empty meaning all exceptions when
excludeis also empty.
exclude: exceptions that should not be retried.
maxAttempts: maximum number of retry attempts, default is 3.
backoff: retry waiting strategy using
@Backoff. The default delay is 1000 ms; here it is set to 2000 ms.
multiplierdefines the delay multiplier; setting it to 1.5 yields delays of 2 s, 3 s, and 4.5 s for successive attempts.
@Recover
<code>@Recover
public int recover(Exception e, int code) {
System.out.println("回调方法执行!!!!");
// log to database or other actions
return 400;
}</code>When retries are exhausted,
RetryOperationscan delegate to a
RecoveryCallback. Spring‑retry also provides the
@Recoverannotation for handling failed retries. The recovery method must have the same return type as the
@Retryablemethod, its first parameter must be a
Throwablematching the exception configured, and it must reside in the same class.
Precautions
Because it is based on AOP, self‑invocation within the same class is not supported.
If a retry fails and you need post‑processing via
@Recover, the retry method must return
void.
Do not use
try/catchinside the retry method; let exceptions propagate outward.
The
@Recovermethod must be in the same class as the
@Retryablemethod, and its first parameter must be the exception thrown by
@Retryable.
Conclusion
This article introduced the use of Spring Boot's
@Retryable, its typical scenarios, and important considerations. It is useful when you need to implement retry logic in a clean, annotation‑driven way.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.