Configuring Custom BackOff Policy for RetryTemplate (using RetryTemplateBuilder)

Hi everybody, in this post under Spring Retry I will show you with example how to configure custom BackOff policy using RetryTemplateBuilder.

For the example we will use the below service class

Service1 class


public class Service1 {
    private int i = 0;
    private int j = 0;

    public void executeWithException() {
        i = i + 1;
        System.out.println("Executing method 'executeWithException' : " + i);
        throw new NullPointerException();
    }

    public void executeWithoutException() {
        j = j + 1;
        System.out.println("Executing method 'executeWithoutException' : " + j);
    }

    public String recovery() {
        return "Recovered";
    }
}

As shown in above code, the service class has three methods “executeWithException” which throws exception when executed, “executeWithoutException” which doesn’t throw exception when executed, and recovery method.

We will now create a custom BackOff policy. For this we create a custom version of FixedBackOffPolicy as shown below

CustomFixedBackOffPolicy


import org.springframework.retry.backoff.BackOffInterruptedException;
import org.springframework.retry.backoff.FixedBackOffPolicy;

public class CustomFixedBackOffPolicy extends FixedBackOffPolicy {
    @Override
    protected void doBackOff() throws BackOffInterruptedException {
        System.out.println("Backing off for: " + this.getBackOffPeriod());
        super.doBackOff();
    }
}

As shown in the above code, we created a custom version of FixedBackOffPolicy named “CustomFixedBackOffPolicy” by extending Spring’s FixedBackOffPolicy. We override “doBackOff” method and add print statement which will display for how long the
Spring Retry will wait for before restarting the failed operation.

Now lets see xml configuration

XML configuration


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="backOffPolicy" class="CustomFixedBackOffPolicy">
        <property name="backOffPeriod" value="120000"/>
    </bean>

    <bean id="service1" class="Service1"/>
</beans>

In the above xml code, we created a bean for “CustomFixedBackOffPolicy” and “Service1” class

Now lets see the main class where we configure RetryTemplate with our custom BackOff policy.

Main


1  import org.springframework.context.ApplicationContext;
2  import org.springframework.context.support.ClassPathXmlApplicationContext;
3  import org.springframework.retry.backoff.BackOffPolicy;
4  import org.springframework.retry.support.RetryTemplate;
5  
6  public class Example24 {
7      public static void main(String[] args) {
8          ApplicationContext context = new ClassPathXmlApplicationContext("Example24.xml");
9          Service1 service1 = (Service1)context.getBean("service1");
10         BackOffPolicy backOffPolicy = (BackOffPolicy) context.getBean("backOffPolicy");
11         
12         RetryTemplate retryTemplate = RetryTemplate.builder().maxAttempts(5).customBackoff(backOffPolicy).build();
13         
14         try {
15             retryTemplate.execute((retryContext) -> { service1.executeWithException(); return null; });
16         } catch(NullPointerException excep) {
17             excep.printStackTrace();
18         }
19     }
20 }

In the above code, at line 9, we get an instance of our Service1 class

At line 10, we get an instance of CustomFixedBackOffPolicy class.

At line 12, We create an instance of RetryTemplateBuilder by calling static “builder” method on RetryTemplate class and using method chaining
1) we configure the max attempts by calling “maxAttempts” method
2) we configure the custom backOffPolicy by calling “customBackoff” method and passing the backOffPolicy instance (got at line 10) as an argument.

Then finally we call “build” method, this will create a RetryTemplate instance configured to run for 5 attempts with a custom back off policy of 120000 ms.

In this way we can configure RetryTemplate to have a custom BackOffPolicy.

Below is the output

Output


[INFO] ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6576fe71: startup date [Sat Apr 30 09:18:31 IST 2022]; root of context hierarchy
[INFO] XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [Example24.xml]
Executing method 'executeWithException' : 1
Backing off for: 120000
Executing method 'executeWithException' : 2
Backing off for: 120000
Executing method 'executeWithException' : 3
Backing off for: 120000
Executing method 'executeWithException' : 4
Backing off for: 120000
Executing method 'executeWithException' : 5
java.lang.NullPointerException
    at Service1.executeWithException(Service1.java:8)
    at Example24.lambda$0(Example24.java:15)
    at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329)
    at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:209)
    at Example24.main(Example24.java:15)

Leave a Reply