diff --git a/src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java b/src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java index 6c46121..e0780e8 100644 --- a/src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java +++ b/src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2016 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. @@ -54,6 +54,7 @@ import org.springframework.util.StringUtils; * * @author Dave Syer * @author Artem Bilan + * @author Gary Russell * @since 1.1 * */ @@ -130,6 +131,9 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn if (retryable == null) { retryable = AnnotationUtils.findAnnotation(method.getDeclaringClass(), Retryable.class); } + if (retryable == null) { + retryable = findAnnotationOnTarget(target, method); + } if (retryable == null) { return this.delegates.put(method, null); } @@ -150,6 +154,16 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn return this.delegates.get(method); } + private Retryable findAnnotationOnTarget(Object target, Method method) { + try { + Method targetMethod = target.getClass().getMethod(method.getName(), method.getParameterTypes()); + return AnnotationUtils.findAnnotation(targetMethod, Retryable.class); + } + catch (Exception e) { + return null; + } + } + private MethodInterceptor getStatelessInterceptor(Object target, Method method, Retryable retryable) { return RetryInterceptorBuilder.stateless() .retryPolicy(getRetryPolicy(retryable)) diff --git a/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java b/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java index 72d6235..5914447 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 the original author or authors. + * Copyright 2014-2016 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. @@ -35,6 +35,7 @@ import org.springframework.retry.interceptor.RetryInterceptorBuilder; /** * @author Dave Syer * @author Artem Bilan + * @author Gary Russell * @since 1.1 */ public class EnableRetryTests { @@ -145,6 +146,16 @@ public class EnableRetryTests { context.close(); } + @Test + public void testInterface() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class); + TheInterface service = context.getBean(TheInterface.class); + service.service1(); + service.service2(); + assertEquals(4, service.getCount()); + context.close(); + } + @Configuration @EnableRetry(proxyTargetClass = true) protected static class TestProxyConfiguration { @@ -216,6 +227,11 @@ public class EnableRetryTests { return new Foo(); } + @Bean + public TheInterface anInterface() { + return new TheClass(); + } + } protected static class Service { @@ -358,4 +374,41 @@ public class EnableRetryTests { } + public static interface TheInterface { + + void service1(); + + @Retryable + void service2(); + + int getCount(); + + } + + public static class TheClass implements TheInterface { + + private int count = 0; + + @Override + @Retryable + public void service1() { + if (count++ < 1) { + throw new RuntimeException("Planned"); + } + } + + @Override + public void service2() { + if (count++ < 3) { + throw new RuntimeException("Planned"); + } + } + + @Override + public int getCount() { + return count; + } + + } + }