Mastering Spring Retry: How @Retryable Simplifies Robust Backend Calls

This article explains how Spring Boot's spring-retry module and the @Retryable annotation enable clean, annotation‑driven retry logic for common failure scenarios, covering configuration, code examples, recovery handling with @Recover, and important usage precautions.

macrozheng
macrozheng
macrozheng
Mastering Spring Retry: How @Retryable Simplifies Robust Backend Calls

Preface

In real work, retry is a very common scenario, such as sending a message failure, remote service call failure, or lock acquisition failure.

Sending message fails.

Calling remote service fails.

Lock acquisition fails.

These errors may be caused by network fluctuations; after waiting, a retry can succeed. Typically developers use try/catch or while loops, but those approaches lack uniformity and require extra code. The spring-retry library allows retry functionality to be added via annotations without intruding on existing business logic.

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

<dependency>
  <groupId>org.springframework.retry</groupId>
  <artifactId>spring-retry</artifactId>
</dependency>

Enable @Retryable

@EnableRetry
@SpringBootApplication
public class HelloApplication {
    public static void main(String[] args) {
        SpringApplication.run(HelloApplication.class, args);
    }
}

Add @Retryable to a Method

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;
    }
}

Explanation of annotation parameters: value: retry only for the specified exception types. include: same as value, default empty; when both include and exclude are empty, all exceptions are retried. exclude: exceptions that should not be retried. maxAttempts: maximum number of retry attempts, default is 3. backoff: retry waiting strategy using @Backoff. The default value is 1000 ms; in the example it is set to 2000 ms. multiplier defaults to 0 (fixed 1 s delay). Setting multiplier to 1.5 makes the delays 2 s, 3 s, and 4.5 s for successive attempts.

When retries are exhausted, RetryOperations can delegate to a RecoveryCallback. Spring‑retry also provides the @Recover annotation for handling the situation after an @Retryable method fails. If no recovery method is defined, the exception is re‑thrown.

@Recover

@Recover
public int recover(Exception e, int code) {
    System.out.println("回调方法执行!!!!");
    // log to database or perform other actions
    return 400;
}

Key points for a @Recover method:

The return type must match the corresponding @Retryable method.

The first parameter must be a Throwable (usually the same exception type configured in @Retryable).

The method must reside in the same class as the retry method.

Precautions

Because it is based on AOP, self‑invocation of methods in the same class is not supported.

If retry fails and you need further processing via @Recover, the retry method must return void.

Method bodies should not contain try/catch; let exceptions propagate outward.

The @Recover method’s first parameter must be the exception type thrown by the @Retryable method; otherwise it will not be recognized.

Conclusion

This article introduced the use of Spring Boot's Retryable annotation, its typical scenarios, and important precautions, demonstrating that it is a useful tool when retry logic is required.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaBackend DevelopmentSpring BootannotationsRetryableSpring Retry
macrozheng
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.