Explanation of Spring Retry Component a Useful Widget in Spring Framework

  • 2021-11-02 00:54:24
  • OfStack

1. Overview

Spring Retry is a component of the Spring framework,
It provides the ability to automatically recall failed operations. This is helpful in cases where the error may occur temporarily (such as transient network failure).

In this article, we'll see the various ways to use Spring Retry: annotations, RetryTemplate, and callbacks.

2. Maven Dependence

Let's start with spring-retry Dependencies are added to our pom.xml In the file:


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

We also need to add Spring AOP to our project:


<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>

You can view Maven Central for the latest version of spring-retry
And spring-aspects Dependencies.

3. Turn on Spring Retry

To enable Spring Retry in the application, we need to set the @EnableRetry Comments are added to our @Configuration Class:


@Configuration
@EnableRetry
public class AppConfig { ... }

4. Use Spring Retry

4.1, @Retryable Without having to recover

We can use @Retryable Annotations add retry functionality to methods:


@Service
public interface MyService {
    @Retryable(value = RuntimeException.class)
    void retryService(String sql);

}

Here, try to retry when RuntimeException is thrown.

According to the default behavior of @ Retryable, retries can occur up to 3 times, with a delay of 1 second between retries.

4.2, @Retryable And @Recover

Now let's use @Recover Note to add 1 recovery method:


@Service
public interface MyService {
    @Retryable(value = SQLException.class)
    void retryServiceWithRecovery(String sql) throws SQLException;
        
    @Recover
    void recover(SQLException e, String sql);
}

Here, when you throw pom.xml1 Retry will try to run. When @Retryable Method fails due to the specified exception, @Recover The annotation defines a separate recovery method.

Therefore, if pom.xml4 Method is thrown after 3 attempts pom.xml1 , then pom.xml6 Method will be called.

The first parameter of the recovery handler should be pom.xml7 Type (optional) and the same return type. The remaining parameters are populated in the same order from the parameter list of the failed method.

4.3. Customize @Retryable The behavior of

To customize the retry behavior, we can use parameters pom.xml9 And spring-retry0 :


@Service
public interface MyService {
    @Retryable( value = SQLException.class, 
      maxAttempts = 2, backoff = @Backoff(delay = 100))
    void retryServiceWithCustomization(String sql) throws SQLException;
}

This will have a maximum of two attempts and a delay of 100 milliseconds.

4.4. Using Spring Properties

We can still find @Retryable properties is used in the annotation.

To demonstrate this 1 point, we will see how to set the spring-retry2 And pom.xml9 To an properties file.

First of all, let's start with a program called spring-retry4 Define attributes in the file of:


retry.maxAttempts=2
retry.maxDelay=100

Then we instructed @Configuration Class loads this file:


@PropertySource("classpath:retryConfig.properties")
public class AppConfig { ... }
// ...

Finally, we can @Retryable Inject into the definition of spring-retry7 And spring-retry8 Value of:


@Service 
public interface MyService { 
  @Retryable( value = SQLException.class, maxAttemptsExpression = "${retry.maxAttempts}",
            backoff = @Backoff(delayExpression = "${retry.maxDelay}")) 
  void retryServiceWithExternalizedConfiguration(String sql) throws SQLException; 
}

Please note that what we are using now is spring-retry9 And spring-aspects0 Instead of pom.xml9 And spring-retry2 .

5. RetryTemplate

5.1, RetryOperations

Spring Retry provides RetryOperations Interface, which provides a set of 1 execute() Methods:


public interface RetryOperations {
    <T> T execute(RetryCallback<T> retryCallback) throws Exception;

    ...
}

execute() Parameters of the method RetryCallback Is an interface to insert business logic that needs to be retried on failure:


<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
0

5.2, RetryTemplate Configure

RetryTemplate Yes RetryOperations 1 implementation of.

Let's take a look at @Configuration Class is configured with 1 RetryTemplate bean of:


<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
1

This RetryPolicy Determines when the operation should be retried.

Among them SimpleRetryPolicy Defines a fixed number of retries, another aspect, BackOffPolicy Used to control the fallback between retry attempts.

Finally, FixedBackOffPolicy Causes the retry to pause for a fixed period of time before continuing.

5.3. Use RetryTemplate

To use retry processing to run the code, we can call retryTemplate.execute() Methods:


<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
2

We can use lambda expressions instead of anonymous classes:


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

6. Listeners

The listener provides another callback when retrying. We can use these to focus on each crosscutting point across different retries.

6.1. Add a callback

Callback in RetryListener Interface provides:


<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
4

@Configuration0 And @Configuration1 Is executed before and after the entire retry, while @Configuration2 Apply to a single RetryCallback Call.

6.2. Register the listener

Next, we will put our listener @Configuration4 Register with our RetryTemplate bean:


<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
5

7. Test results

To complete our example, let's verify the results of 1:


<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
6

As you can see from the test log, we have configured it correctly RetryTemplate And RetryListener :

2020-01-09 20:04:10 [main] INFO c.p.s.DefaultListenerSupport - onOpen
2020-01-09 20:04:10 [main] INFO c.pinmost.springretry.MyServiceImpl - throw RuntimeException in method templateRetryService()
2020-01-09 20:04:10 [main] INFO c.p.s.DefaultListenerSupport - onError
2020-01-09 20:04:12 [main] INFO c.pinmost.springretry.MyServiceImpl - throw RuntimeException in method templateRetryService()
2020-01-09 20:04:12 [main] INFO c.p.s.DefaultListenerSupport - onError
2020-01-09 20:04:12 [main] INFO c.p.s.DefaultListenerSupport - onClose

8. Conclusion

In this article, we saw how to use annotations, RetryTemplate And callback listener to use Spring Retry.

Original address: https://www.baeldung.com/spring-retry


Related articles: