Override retry listeners for each Retryable method
This commit is contained in:
@@ -93,7 +93,7 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private RetryListener[] listeners;
|
||||
private RetryListener[] defaultListeners;
|
||||
|
||||
/**
|
||||
* @param sleeper the sleeper to set
|
||||
@@ -127,12 +127,12 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn
|
||||
|
||||
/**
|
||||
* Retry listeners to apply to all operations.
|
||||
* @param listeners the listeners
|
||||
* @param defaultListeners the listeners
|
||||
*/
|
||||
public void setListeners(Collection<RetryListener> listeners) {
|
||||
ArrayList<RetryListener> retryListeners = new ArrayList<RetryListener>(listeners);
|
||||
public void setDefaultListeners(Collection<RetryListener> defaultListeners) {
|
||||
ArrayList<RetryListener> retryListeners = new ArrayList<RetryListener>(defaultListeners);
|
||||
AnnotationAwareOrderComparator.sort(retryListeners);
|
||||
this.listeners = retryListeners.toArray(new RetryListener[0]);
|
||||
this.defaultListeners = retryListeners.toArray(new RetryListener[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -208,7 +208,7 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn
|
||||
}
|
||||
|
||||
private MethodInterceptor getStatelessInterceptor(Object target, Method method, Retryable retryable) {
|
||||
RetryTemplate template = createTemplate();
|
||||
RetryTemplate template = createTemplate(retryable.listeners());
|
||||
template.setRetryPolicy(getRetryPolicy(retryable));
|
||||
template.setBackOffPolicy(getBackoffPolicy(retryable.backoff()));
|
||||
return RetryInterceptorBuilder.stateless()
|
||||
@@ -219,7 +219,7 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn
|
||||
}
|
||||
|
||||
private MethodInterceptor getStatefulInterceptor(Object target, Method method, Retryable retryable) {
|
||||
RetryTemplate template = createTemplate();
|
||||
RetryTemplate template = createTemplate(retryable.listeners());
|
||||
template.setRetryContextCache(this.retryContextCache);
|
||||
|
||||
CircuitBreaker circuit = AnnotationUtils.findAnnotation(method, CircuitBreaker.class);
|
||||
@@ -254,14 +254,24 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn
|
||||
.build();
|
||||
}
|
||||
|
||||
private RetryTemplate createTemplate() {
|
||||
private RetryTemplate createTemplate(String[] listenersBeanNames) {
|
||||
RetryTemplate template = new RetryTemplate();
|
||||
if (listeners!=null) {
|
||||
template.setListeners(listeners);
|
||||
if (listenersBeanNames.length > 0) {
|
||||
template.setListeners(getListenersBeans(listenersBeanNames));
|
||||
} else if (defaultListeners !=null) {
|
||||
template.setListeners(defaultListeners);
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
private RetryListener[] getListenersBeans(String[] listenersBeanNames) {
|
||||
RetryListener[] listeners = new RetryListener[listenersBeanNames.length];
|
||||
for (int i = 0; i < listeners.length; i++) {
|
||||
listeners[i] = beanFactory.getBean(listenersBeanNames[i], RetryListener.class);
|
||||
}
|
||||
return listeners;
|
||||
}
|
||||
|
||||
private MethodInvocationRecoverer<?> getRecoverer(Object target, Method method) {
|
||||
if (target instanceof MethodInvocationRecoverer) {
|
||||
return (MethodInvocationRecoverer<?>) target;
|
||||
|
||||
@@ -134,7 +134,7 @@ public class RetryConfiguration extends AbstractPointcutAdvisor implements Intro
|
||||
interceptor.setRetryContextCache(retryContextCache);
|
||||
}
|
||||
if (retryListeners != null) {
|
||||
interceptor.setListeners(retryListeners);
|
||||
interceptor.setDefaultListeners(retryListeners);
|
||||
}
|
||||
if (methodArgumentsKeyGenerator != null) {
|
||||
interceptor.setKeyGenerator(methodArgumentsKeyGenerator);
|
||||
|
||||
@@ -118,4 +118,10 @@ public @interface Retryable {
|
||||
*/
|
||||
String exceptionExpression() default "";
|
||||
|
||||
/**
|
||||
* Bean names of retry listeners to use instead of default ones defined in Spring context
|
||||
* @return retry listeners bean names
|
||||
*/
|
||||
String[] listeners() default {};
|
||||
|
||||
}
|
||||
|
||||
@@ -43,6 +43,17 @@ public class EnableRetryWithListenersTests {
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void overrideListener() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
TestConfigurationMultipleListeners.class);
|
||||
ServiceWithOverriddenListener service = context.getBean(ServiceWithOverriddenListener.class);
|
||||
service.service();
|
||||
assertEquals(1, context.getBean(TestConfigurationMultipleListeners.class).count1);
|
||||
assertEquals(0, context.getBean(TestConfigurationMultipleListeners.class).count2);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRetry(proxyTargetClass = true)
|
||||
protected static class TestConfiguration {
|
||||
@@ -67,6 +78,42 @@ public class EnableRetryWithListenersTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRetry(proxyTargetClass = true)
|
||||
protected static class TestConfigurationMultipleListeners {
|
||||
|
||||
private int count1 = 0;
|
||||
private int count2 = 0;
|
||||
|
||||
@Bean
|
||||
public ServiceWithOverriddenListener service() {
|
||||
return new ServiceWithOverriddenListener();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RetryListener listener1() {
|
||||
return new RetryListenerSupport() {
|
||||
@Override
|
||||
public <T, E extends Throwable> void close(RetryContext context,
|
||||
RetryCallback<T, E> callback, Throwable throwable) {
|
||||
count1++;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RetryListener listener2() {
|
||||
return new RetryListenerSupport() {
|
||||
@Override
|
||||
public <T, E extends Throwable> void close(RetryContext context,
|
||||
RetryCallback<T, E> callback, Throwable throwable) {
|
||||
count2++;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class Service {
|
||||
|
||||
private int count = 0;
|
||||
@@ -84,4 +131,21 @@ public class EnableRetryWithListenersTests {
|
||||
|
||||
}
|
||||
|
||||
protected static class ServiceWithOverriddenListener {
|
||||
|
||||
private int count = 0;
|
||||
|
||||
@Retryable(backoff = @Backoff(delay = 1000), listeners = "listener1")
|
||||
public void service() {
|
||||
if (count++ < 2) {
|
||||
throw new RuntimeException("Planned");
|
||||
}
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user