Add support for RetryListener beans in @EnableRetry

This commit is contained in:
Dave Syer
2016-08-22 11:37:07 +01:00
parent cc97238158
commit 1cb4f19cf1
3 changed files with 41 additions and 8 deletions

View File

@@ -18,6 +18,8 @@ package org.springframework.retry.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -28,7 +30,9 @@ import org.springframework.aop.IntroductionInterceptor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.retry.RetryListener;
import org.springframework.retry.RetryPolicy;
import org.springframework.retry.backoff.BackOffPolicy;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
@@ -74,6 +78,8 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn
private BeanFactory beanFactory;
private RetryListener[] listeners;
/**
* @param sleeper the sleeper to set
*/
@@ -104,6 +110,16 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn
this.newMethodArgumentsIdentifier = newMethodArgumentsIdentifier;
}
/**
* Retry listeners to apply to all operations.
* @param listeners the listeners
*/
public void setListeners(Collection<RetryListener> listeners) {
ArrayList<RetryListener> retryListeners = new ArrayList<RetryListener>(listeners);
AnnotationAwareOrderComparator.sort(retryListeners);
this.listeners = retryListeners.toArray(new RetryListener[0]);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
@@ -167,15 +183,17 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn
}
private MethodInterceptor getStatelessInterceptor(Object target, Method method, Retryable retryable) {
RetryTemplate template = createTemplate();
template.setRetryPolicy(getRetryPolicy(retryable));
template.setBackOffPolicy(getBackoffPolicy(retryable.backoff()));
return RetryInterceptorBuilder.stateless()
.retryPolicy(getRetryPolicy(retryable))
.backOffPolicy(getBackoffPolicy(retryable.backoff()))
.retryOperations(template)
.recoverer(getRecoverer(target, method))
.build();
}
private MethodInterceptor getStatefulInterceptor(Object target, Method method, Retryable retryable) {
RetryTemplate template = new RetryTemplate();
RetryTemplate template = createTemplate();
template.setRetryContextCache(this.retryContextCache);
CircuitBreaker circuit = AnnotationUtils.findAnnotation(method, CircuitBreaker.class);
@@ -207,6 +225,12 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn
.build();
}
private RetryTemplate createTemplate() {
RetryTemplate template = new RetryTemplate();
template.setListeners(listeners);
return template;
}
private MethodInvocationRecoverer<?> getRecoverer(Object target, Method method) {
if (target instanceof MethodInvocationRecoverer) {
return (MethodInvocationRecoverer<?>) target;

View File

@@ -19,6 +19,7 @@ package org.springframework.retry.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -39,6 +40,7 @@ import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.retry.RetryListener;
import org.springframework.retry.backoff.Sleeper;
import org.springframework.retry.interceptor.MethodArgumentsKeyGenerator;
import org.springframework.retry.interceptor.NewMethodArgumentsIdentifier;
@@ -68,6 +70,9 @@ public class RetryConfiguration extends AbstractPointcutAdvisor implements Intro
@Autowired(required = false)
private RetryContextCache retryContextCache;
@Autowired(required = false)
private List<RetryListener> retryListeners;
@Autowired(required = false)
private MethodArgumentsKeyGenerator methodArgumentsKeyGenerator;
@@ -127,6 +132,9 @@ public class RetryConfiguration extends AbstractPointcutAdvisor implements Intro
if (retryContextCache != null) {
interceptor.setRetryContextCache(retryContextCache);
}
if (retryListeners != null) {
interceptor.setListeners(retryListeners);
}
if (methodArgumentsKeyGenerator != null) {
interceptor.setKeyGenerator(methodArgumentsKeyGenerator);
}

View File

@@ -208,7 +208,7 @@ public class RetryTemplate implements RetryOperations {
@Override
public final <T, E extends Throwable> T execute(RetryCallback<T, E> retryCallback,
RecoveryCallback<T> recoveryCallback, RetryState retryState)
throws E, ExhaustedRetryException {
throws E, ExhaustedRetryException {
return doExecute(retryCallback, recoveryCallback, retryState);
}
@@ -227,7 +227,7 @@ public class RetryTemplate implements RetryOperations {
*/
protected <T, E extends Throwable> T doExecute(RetryCallback<T, E> retryCallback,
RecoveryCallback<T> recoveryCallback, RetryState state)
throws E, ExhaustedRetryException {
throws E, ExhaustedRetryException {
RetryPolicy retryPolicy = this.retryPolicy;
BackOffPolicy backOffPolicy = this.backOffPolicy;
@@ -291,8 +291,6 @@ public class RetryTemplate implements RetryOperations {
lastException = e;
doOnErrorInterceptors(retryCallback, context, e);
try {
registerThrowable(retryPolicy, state, context, e);
}
@@ -300,6 +298,9 @@ public class RetryTemplate implements RetryOperations {
throw new TerminatedRetryException("Could not register throwable",
ex);
}
finally {
doOnErrorInterceptors(retryCallback, context, e);
}
if (canRetry(retryPolicy, context) && !context.isExhaustedOnly()) {
try {
@@ -469,7 +470,7 @@ public class RetryTemplate implements RetryOperations {
private RetryContext doOpenInternal(RetryPolicy retryPolicy, RetryState state) {
RetryContext context = retryPolicy.open(RetrySynchronizationManager.getContext());
if (state!=null) {
if (state != null) {
context.setAttribute(RetryContext.STATE_KEY, state.getKey());
}
return context;