diff --git a/src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java b/src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java index 26b5300..d25d850 100644 --- a/src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java +++ b/src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java @@ -195,7 +195,12 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn private Retryable findAnnotationOnTarget(Object target, Method method) { try { Method targetMethod = target.getClass().getMethod(method.getName(), method.getParameterTypes()); - return AnnotationUtils.findAnnotation(targetMethod, Retryable.class); + Retryable retryable = AnnotationUtils.findAnnotation(targetMethod, Retryable.class); + if (retryable == null) { + retryable = AnnotationUtils.findAnnotation(targetMethod.getDeclaringClass(), Retryable.class); + } + + return retryable; } catch (Exception e) { return null; diff --git a/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java b/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java index 3e1d93f..6b19cf0 100644 --- a/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java +++ b/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java @@ -168,6 +168,17 @@ public class EnableRetryTests { context.close(); } + @Test + public void testImplementation() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class); + NotAnnotatedInterface service = context.getBean(NotAnnotatedInterface.class); + service.service1(); + service.service2(); + assertEquals(5, service.getCount()); + context.close(); + } + + @Test public void testExpression() throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( @@ -321,6 +332,11 @@ public class EnableRetryTests { return new TheClass(); } + @Bean + public NotAnnotatedInterface notAnnotatedInterface() { + return new RetryableImplementation(); + } + } protected static class Service { @@ -538,4 +554,41 @@ public class EnableRetryTests { } + public static interface NotAnnotatedInterface { + + void service1(); + + void service2(); + + int getCount(); + + } + + @Retryable + public static class RetryableImplementation implements NotAnnotatedInterface { + + private int count = 0; + + @Override + public void service1() { + if (count++ < 2) { + throw new RuntimeException("Planned"); + } + } + + @Override + public void service2() { + if (count++ < 4) { + throw new RuntimeException("Planned"); + } + } + + @Override + public int getCount() { + return count; + } + + } + + }