In this post under Spring Retry, I will show with example how to configure RetryListener using annotations.
For our example we will need the below “CustomRetryListener2” class
CustomRetryListener2
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.RetryListener;
import org.springframework.stereotype.Component;
@Component
public class CustomRetryListener2 implements RetryListener {
@Override
public <T, E extends Throwable> void close(RetryContext arg0, RetryCallback<T, E> arg1, Throwable arg2) {
System.out.println("Calling 'close' method");
}
@Override
public <T, E extends Throwable> void onError(RetryContext arg0, RetryCallback<T, E> arg1, Throwable arg2) {
System.out.println("Calling 'onError' method");
}
@Override
public <T, E extends Throwable> boolean open(RetryContext arg0, RetryCallback<T, E> arg1) {
System.out.println("Calling 'open' method");
return true;
}
}
As you see the “CustomRetryListener2” class implements “RetryListener” interface. It provides implementations for “open”, “close”, and “onError” methods.
We annotate the class “@Component” annotation.
Next we need the below Service class
Service7
1 import org.springframework.retry.annotation.Retryable;
2 import org.springframework.stereotype.Service;
3
4 @Service
5 public class Service7 {
6 private int i = 0;
7
8 @Retryable(listeners= "customRetryListener")
9 public void executeWithException() {
10 i = i + 1;
11 System.out.println("Executing method 'executeWithException' : " + i);
12 throw new NullPointerException();
13 }
14 }
In the above Service7 class code, at line 8 we annotate the method which has to be retried by using @Retryable annotation. We also mention listener by setting “listeners” attribute of the annotation to “customRetryListener”. Here “customRetryListener” is the bean name. The bean definition of “customRetryListener” is defined in the main class which is shown next.
Next is the main class where we will use the above classes
Main class
1 import org.springframework.context.ApplicationContext;
2 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
3 import org.springframework.context.annotation.Bean;
4 import org.springframework.context.annotation.Configuration;
5 import org.springframework.retry.annotation.EnableRetry;
6
7 @Configuration
8 @EnableRetry
9 public class Example28 {
10 public static void main(String[] args) {
11 ApplicationContext context = new AnnotationConfigApplicationContext(Example28.class);
12 Service7 service7 = (Service7) context.getBean("service7");
13
14 try {
15 service7.executeWithException();
16 } catch(Exception excep) {
17 excep.printStackTrace();
18 }
19 }
20
21 @Bean(name="service7")
22 public Service7 getService() {
23 return new Service7();
24 }
25
26 @Bean(name="customRetryListener")
27 public CustomRetryListener2 getListener() {
28 return new CustomRetryListener2();
29 }
30 }
As you can see in the above code, the class is annotated with “@Configuration” annotation indicating that this class will contain bean definitions.
At line 8, we enabled Spring Retry by annotating the class with “@EnableRetry” annotation.
At line 21, we create a “service7” bean.
At line 26, we create a “customRetryListener” bean.
At line 15, we call the service class method which has to be retried.
In this way, using annotations we configure RetryListener.
Below is the output
Output
[INFO] AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1f17ae12: startup date [Sat May 28 09:57:36 IST 2022]; root of context hierarchy
Calling 'open' method
Executing method 'executeWithException' : 1
Calling 'onError' method
Executing method 'executeWithException' : 2
Calling 'onError' method
Executing method 'executeWithException' : 3
Calling 'onError' method
Calling 'close' method
java.lang.NullPointerException
at Service7.executeWithException(Service7.java:12)
at Service7$$FastClassBySpringCGLIB$$560f7442.invoke(<generated>)
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.retry.annotation.AnnotationAwareRetryOperationsInterceptor.invoke(AnnotationAwareRetryOperationsInterceptor.java:163)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671)
at Service7$$EnhancerBySpringCGLIB$$a3a3d071.executeWithException(<generated>)
at Example28.main(Example28.java:15)
[INFO] AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1f17ae12: startup date [Sat May 28 09:57:36 IST 2022]; root of context hierarchy
Calling 'open' method
Executing method 'executeWithException' : 1
Calling 'onError' method
Executing method 'executeWithException' : 2
Calling 'onError' method
Executing method 'executeWithException' : 3
Calling 'onError' method
Calling 'close' method
java.lang.NullPointerException
at Service7.executeWithException(Service7.java:12)
at Service7$$FastClassBySpringCGLIB$$560f7442.invoke(<generated>)
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.retry.annotation.AnnotationAwareRetryOperationsInterceptor.invoke(AnnotationAwareRetryOperationsInterceptor.java:163)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671)
at Service7$$EnhancerBySpringCGLIB$$a3a3d071.executeWithException(<generated>)
at Example28.main(Example28.java:15)
Note
Press like button if you like the post. Also share your opinion regarding posts through comments. Also mention what other framework you want me to cover through comments.