diff --git a/src/main/java/org/springframework/retry/annotation/RecoverAnnotationRecoveryHandler.java b/src/main/java/org/springframework/retry/annotation/RecoverAnnotationRecoveryHandler.java index 4d42bf1..250d49e 100644 --- a/src/main/java/org/springframework/retry/annotation/RecoverAnnotationRecoveryHandler.java +++ b/src/main/java/org/springframework/retry/annotation/RecoverAnnotationRecoveryHandler.java @@ -40,6 +40,7 @@ import org.springframework.util.ReflectionUtils.MethodCallback; * * @author Dave Syer * @author Josh Long + * @author Aldo Sinanaj */ public class RecoverAnnotationRecoveryHandler implements MethodInvocationRecoverer { @@ -116,8 +117,8 @@ public class RecoverAnnotationRecoveryHandler implements MethodInvocationReco Recover recover = AnnotationUtils.findAnnotation(method, Recover.class); if (recover != null - && failingMethod.getReturnType().isAssignableFrom( - method.getReturnType())) { + && method.getReturnType().isAssignableFrom( + failingMethod.getReturnType())) { Class[] parameterTypes = method.getParameterTypes(); if (parameterTypes.length > 0 && Throwable.class @@ -136,6 +137,19 @@ public class RecoverAnnotationRecoveryHandler implements MethodInvocationReco } }); classifier.setTypeMap(types); + optionallyFilterMethodsBy(failingMethod.getReturnType()); + } + + private void optionallyFilterMethodsBy(Class returnClass) { + Map filteredMethods = new HashMap(); + for (Method method : methods.keySet()) { + if (method.getReturnType() == returnClass) { + filteredMethods.put(method, methods.get(method)); + } + } + if (filteredMethods.size() > 0) { + methods = filteredMethods; + } } private static class SimpleMetadata { diff --git a/src/test/java/org/springframework/retry/annotation/RecoverAnnotationRecoveryHandlerTests.java b/src/test/java/org/springframework/retry/annotation/RecoverAnnotationRecoveryHandlerTests.java index 2d2b1f7..29b7c4b 100644 --- a/src/test/java/org/springframework/retry/annotation/RecoverAnnotationRecoveryHandlerTests.java +++ b/src/test/java/org/springframework/retry/annotation/RecoverAnnotationRecoveryHandlerTests.java @@ -31,7 +31,7 @@ import java.lang.reflect.Method; /** * @author Dave Syer - * + * @author Aldo Sinanaj */ public class RecoverAnnotationRecoveryHandlerTests { @@ -94,6 +94,28 @@ public class RecoverAnnotationRecoveryHandlerTests { } + @Test + public void specificReturnTypeRecoverMethod() { + RecoverAnnotationRecoveryHandler fooHandler = new RecoverAnnotationRecoveryHandler( + new InheritanceReturnTypeRecover(), ReflectionUtils.findMethod(InheritanceReturnTypeRecover.class, + "foo", String.class)); + assertEquals(1, + fooHandler.recover(new Object[] { "Aldo" }, new RuntimeException("Planned"))); + assertEquals(2, + fooHandler.recover(new Object[] { "Aldo" }, new IllegalStateException("Planned"))); + + } + + @Test + public void parentReturnTypeRecoverMethod() { + RecoverAnnotationRecoveryHandler barHandler = new RecoverAnnotationRecoveryHandler( + new InheritanceReturnTypeRecover(), ReflectionUtils.findMethod(InheritanceReturnTypeRecover.class, + "bar", String.class)); + assertEquals(3, + barHandler.recover(new Object[] { "Aldo" }, new RuntimeException("Planned"))); + + } + private static class InAccessibleRecover { @Retryable @@ -181,5 +203,33 @@ public class RecoverAnnotationRecoveryHandlerTests { } + protected static class InheritanceReturnTypeRecover { + + @Retryable + public Integer foo(String name) { + return 0; + } + + @Retryable + public Double bar(String name) { + return 0.0; + } + + @Recover + public Integer baz(RuntimeException re, String name) { + return 1; + } + + @Recover + public Integer qux(IllegalStateException re, String name) { + return 2; + } + + @Recover + public Number quux(RuntimeException re, String name) { + return 3; + } + + } }