Add support for RetryListener beans in @EnableRetry
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user