Spring Retry simple example (using interceptor)

In this post under Spring Retry, I will explain how to configure Spring Retry framework into your application using Spring AOP with simple example.

At minimum, you need the below jars in your classpath
1) spring-retry-1.3.1.jar
2) commons-logging-1.2.jar
3) spring-core-4.3.22.RELEASE.jar
4) spring-aop-4.3.22.REELEASE.jar
5) spring-beans-4.3.22.RELEASE.jar
6) spring-context-4.3.22.RELEASE.jar
7) spring-expression-4.3.22.RELEASE.jar
8) aspectjweaver-1.8.9.jar

For our example we will use the below service class

Service1


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

To add Spring Retry functionality in AOP style we will take help of “org.springframework.retry.interceptor.RetryOperationsInterceptor”.

We will wrap our service class executeWithException method, with the above interceptor using xml as shown below


1  <?xml version="1.0" encoding="UTF-8"?>
2  <beans xmlns="http://www.springframework.org/schema/beans"
3  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4  xmlns:aop = "http://www.springframework.org/schema/aop"
5  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
6  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
7      <aop:config>
8          <aop:pointcut id="transactional" expression="execution(* Service1.executeWithException(..))"/>
9          <aop:advisor pointcut-ref="transactional" advice-ref="retryAdvice"/>
10     </aop:config>
11     
12     <bean id="retryAdvice" class="org.springframework.retry.interceptor.RetryOperationsInterceptor"/>
13     
14     <bean id="service1" class="Service1"/>
15 </beans>

In the above xml code, at line 12, we create an advice bean by name “retryAdvice” and of class “RetryOperationsInterceptor”.

At line 8, we define a pointcut

At line 9, we create an advisor which says retryAdvice bean will wrap around “Service1” class “executeWithException” method.

In this way we can use Spring Retry functionality using Spring AOP.

Below is the main class

Main Class


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Example38 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("Example38.xml");
        Service1 service1 = (Service1)context.getBean("service1");

        service1.executeWithException();
    }
}

When you run the above code, you will get the below output

Output

[INFO] ClassPathXmlApplicationContext – Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6576fe71: startup date [Sat Oct 23 17:25:20 IST 2021]; root of context hierarchy
[INFO] XmlBeanDefinitionReader – Loading XML bean definitions from class path resource [Example38.xml]
Executing method ‘executeWithException’ : 1
Executing method ‘executeWithException’ : 2
Executing method ‘executeWithException’ : 3
Exception in thread “main”
java.lang.NullPointerException
at Service1.executeWithException(Service1.java:8)
at Service1$$FastClassBySpringCGLIB$$560f743c.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.retry.interceptor.RetryOperationsInterceptor$1.doWithRetry(RetryOperationsInterceptor.java:93)
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329)
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:209)
at org.springframework.retry.interceptor.RetryOperationsInterceptor.invoke(RetryOperationsInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671)
at Service1$$EnhancerBySpringCGLIB$$5f51eb67.executeWithException()
at Example38.main(Example38.java:9)

Leave a Reply