diff --git a/src/main/java/org/springframework/retry/annotation/EnableRetry.java b/src/main/java/org/springframework/retry/annotation/EnableRetry.java index 6cec7aa..30a6ff2 100644 --- a/src/main/java/org/springframework/retry/annotation/EnableRetry.java +++ b/src/main/java/org/springframework/retry/annotation/EnableRetry.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,8 @@ import java.lang.annotation.Target; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.Import; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.AliasFor; /** * Global enabler for @Retryable annotations in Spring beans. If this is @@ -32,7 +34,8 @@ import org.springframework.context.annotation.Import; * the annotations. * * @author Dave Syer - * @since 2.0 + * @author Yanming Zhou + * @since 1.1 * */ @Target(ElementType.TYPE) @@ -47,6 +50,17 @@ public @interface EnableRetry { * standard Java interface-based proxies. The default is {@code false}. * @return whether to proxy or not to proxy the class */ + @AliasFor(annotation = EnableAspectJAutoProxy.class) boolean proxyTargetClass() default false; + /** + * Indicate the order in which the {@link RetryConfiguration} AOP advice should + * be applied. + *

+ * The default is {@code Ordered.LOWEST_PRECEDENCE - 1} in order to make sure the + * advice is applied before other advices with {@link Ordered#LOWEST_PRECEDENCE} order + * (e.g. an advice responsible for {@code @Transactional} behavior). + */ + int order() default Ordered.LOWEST_PRECEDENCE - 1; + } diff --git a/src/main/java/org/springframework/retry/annotation/RetryConfiguration.java b/src/main/java/org/springframework/retry/annotation/RetryConfiguration.java index cae4c3b..e8c35d3 100644 --- a/src/main/java/org/springframework/retry/annotation/RetryConfiguration.java +++ b/src/main/java/org/springframework/retry/annotation/RetryConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2022 the original author or authors. + * Copyright 2014-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,9 +40,12 @@ import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.ImportAware; import org.springframework.context.annotation.Role; import org.springframework.core.OrderComparator; +import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.type.AnnotationMetadata; import org.springframework.retry.RetryListener; import org.springframework.retry.backoff.Sleeper; import org.springframework.retry.interceptor.MethodArgumentsKeyGenerator; @@ -62,6 +65,7 @@ import org.springframework.util.ReflectionUtils.MethodCallback; * @author Dave Syer * @author Artem Bilan * @author Markus Heiden + * @author Yanming Zhou * @since 1.1 * */ @@ -69,7 +73,9 @@ import org.springframework.util.ReflectionUtils.MethodCallback; @Role(BeanDefinition.ROLE_INFRASTRUCTURE) @Component public class RetryConfiguration extends AbstractPointcutAdvisor - implements IntroductionAdvisor, BeanFactoryAware, InitializingBean { + implements IntroductionAdvisor, BeanFactoryAware, InitializingBean, ImportAware { + + protected AnnotationAttributes enableRetry; private Advice advice; @@ -87,6 +93,12 @@ public class RetryConfiguration extends AbstractPointcutAdvisor private BeanFactory beanFactory; + @Override + public void setImportMetadata(AnnotationMetadata importMetadata) { + this.enableRetry = AnnotationAttributes + .fromMap(importMetadata.getAnnotationAttributes(EnableRetry.class.getName())); + } + @Override public void afterPropertiesSet() throws Exception { this.retryContextCache = findBean(RetryContextCache.class); @@ -101,6 +113,9 @@ public class RetryConfiguration extends AbstractPointcutAdvisor if (this.advice instanceof BeanFactoryAware) { ((BeanFactoryAware) this.advice).setBeanFactory(this.beanFactory); } + if (this.enableRetry != null) { + setOrder(enableRetry.getNumber("order").intValue()); + } } private List findBeans(Class type) { diff --git a/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java b/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java index 7bff6ae..468a553 100644 --- a/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java +++ b/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2021 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,6 +55,7 @@ import static org.junit.Assert.fail; * @author Artem Bilan * @author Gary Russell * @author Aldo Sinanaj + * @author Yanming Zhou * @since 1.1 */ public class EnableRetryTests { @@ -98,6 +99,15 @@ public class EnableRetryTests { context.close(); } + @Test + public void order() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + TestOrderConfiguration.class); + RetryConfiguration config = context.getBean(RetryConfiguration.class); + assertEquals(1, config.getOrder()); + context.close(); + } + @Test public void marker() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class); @@ -325,6 +335,17 @@ public class EnableRetryTests { } + @Configuration + @EnableRetry(order = 1) + protected static class TestOrderConfiguration { + + @Bean + public Service service() { + return new Service(); + } + + } + @Configuration @EnableRetry protected static class TestConfiguration {