From 87307292a56aecd0060538973eb1f34b1d227e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henning=20P=C3=B6ttker?= Date: Mon, 28 Nov 2022 22:57:01 +0100 Subject: [PATCH] Deprecate RetryListenSupport for default methods Deprecate a `RetryListenerSupport` in favor of `default` methods in `RetryListener` interface --- README.md | 2 - .../springframework/retry/RetryListener.java | 13 +++-- .../retry/listener/RetryListenerSupport.java | 6 ++- .../retry/stats/StatisticsListener.java | 7 +-- .../retry/annotation/EnableRetryTests.java | 4 +- .../EnableRetryWithListenersTests.java | 8 +-- .../RetryOperationsInterceptorTests.java | 13 +++-- ...atefulRetryOperationsInterceptorTests.java | 5 +- .../listener/RetryListenerSupportTests.java | 6 +++ .../retry/listener/RetryListenerTests.java | 51 ++++++++++++++++--- .../retry/stats/StatisticsListenerTests.java | 15 +++--- .../retry/support/RetryTemplateTests.java | 5 +- 12 files changed, 97 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 5e747a5a..d905aaa2 100644 --- a/README.md +++ b/README.md @@ -364,8 +364,6 @@ If there has been an error, it is the last one thrown by the `RetryCallback`. Note that when there is more than one listener, they are in a list, so there is an order. In this case, `open` is called in the same order, while `onSuccess`, `onError`, and `close` are called in reverse order. -`RetryListenerSupport` is provided, with no-op implementations; you can extend this class if you don't need to implement all of the `RetryListener` methods. - ### Listeners for Reflective Method Invocations When dealing with methods that are annotated with `@Retryable` or with Spring AOP intercepted methods, Spring Retry allows a detailed inspection of the method invocation within the `RetryListener` implementation. diff --git a/src/main/java/org/springframework/retry/RetryListener.java b/src/main/java/org/springframework/retry/RetryListener.java index a2c3af19..dabbf15d 100644 --- a/src/main/java/org/springframework/retry/RetryListener.java +++ b/src/main/java/org/springframework/retry/RetryListener.java @@ -23,6 +23,7 @@ * * @author Dave Syer * @author Gary Russell + * @author Henning Pöttker * */ public interface RetryListener { @@ -38,7 +39,9 @@ public interface RetryListener { * @param callback the current {@link RetryCallback}. * @return true if the retry should proceed. */ - boolean open(RetryContext context, RetryCallback callback); + default boolean open(RetryContext context, RetryCallback callback) { + return true; + } /** * Called after the final attempt (successful or not). Allow the listener to clean up @@ -49,7 +52,9 @@ public interface RetryListener { * @param the exception type * @param the return value */ - void close(RetryContext context, RetryCallback callback, Throwable throwable); + default void close(RetryContext context, RetryCallback callback, + Throwable throwable) { + } /** * Called after a successful attempt; allow the listener to throw a new exception to @@ -72,6 +77,8 @@ default void onSuccess(RetryContext context, RetryCallb * @param the return value * @param the exception to throw */ - void onError(RetryContext context, RetryCallback callback, Throwable throwable); + default void onError(RetryContext context, RetryCallback callback, + Throwable throwable) { + } } diff --git a/src/main/java/org/springframework/retry/listener/RetryListenerSupport.java b/src/main/java/org/springframework/retry/listener/RetryListenerSupport.java index abef3119..ae6704c3 100644 --- a/src/main/java/org/springframework/retry/listener/RetryListenerSupport.java +++ b/src/main/java/org/springframework/retry/listener/RetryListenerSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2007 the original author or authors. + * Copyright 2006-2022 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,8 +24,10 @@ * Empty method implementation of {@link RetryListener}. * * @author Dave Syer - * + * @author Henning Pöttker + * @deprecated in favor of the default implementations in {@link RetryListener} */ +@Deprecated(since = "2.0.1", forRemoval = true) public class RetryListenerSupport implements RetryListener { public void close(RetryContext context, RetryCallback callback, diff --git a/src/main/java/org/springframework/retry/stats/StatisticsListener.java b/src/main/java/org/springframework/retry/stats/StatisticsListener.java index 33fd601c..696031bf 100644 --- a/src/main/java/org/springframework/retry/stats/StatisticsListener.java +++ b/src/main/java/org/springframework/retry/stats/StatisticsListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2022 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. @@ -19,15 +19,16 @@ import org.springframework.core.AttributeAccessor; import org.springframework.retry.RetryCallback; import org.springframework.retry.RetryContext; +import org.springframework.retry.RetryListener; import org.springframework.retry.RetryStatistics; -import org.springframework.retry.listener.RetryListenerSupport; import org.springframework.retry.policy.CircuitBreakerRetryPolicy; /** * @author Dave Syer + * @author Henning Pöttker * */ -public class StatisticsListener extends RetryListenerSupport { +public class StatisticsListener implements RetryListener { private final StatisticsRepository repository; diff --git a/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java b/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java index 0d234140..ae916416 100644 --- a/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java +++ b/src/test/java/org/springframework/retry/annotation/EnableRetryTests.java @@ -39,7 +39,6 @@ import org.springframework.retry.backoff.ExponentialBackOffPolicy; import org.springframework.retry.backoff.Sleeper; import org.springframework.retry.interceptor.RetryInterceptorBuilder; -import org.springframework.retry.listener.RetryListenerSupport; import org.springframework.retry.policy.SimpleRetryPolicy; import org.springframework.retry.support.RetryTemplate; @@ -57,6 +56,7 @@ * @author Artem Bilan * @author Gary Russell * @author Aldo Sinanaj + * @author Henning Pöttker * @since 1.1 */ public class EnableRetryTests { @@ -910,7 +910,7 @@ public int getCount() { } - public abstract static class OrderedListener extends RetryListenerSupport implements Ordered { + public abstract static class OrderedListener implements RetryListener, Ordered { } diff --git a/src/test/java/org/springframework/retry/annotation/EnableRetryWithListenersTests.java b/src/test/java/org/springframework/retry/annotation/EnableRetryWithListenersTests.java index 3910d6e5..aeccb680 100644 --- a/src/test/java/org/springframework/retry/annotation/EnableRetryWithListenersTests.java +++ b/src/test/java/org/springframework/retry/annotation/EnableRetryWithListenersTests.java @@ -24,13 +24,13 @@ import org.springframework.retry.RetryCallback; import org.springframework.retry.RetryContext; import org.springframework.retry.RetryListener; -import org.springframework.retry.listener.RetryListenerSupport; import static org.assertj.core.api.Assertions.assertThat; /** * @author Dave Syer * @author Gary Russell + * @author Henning Pöttker * */ public class EnableRetryWithListenersTests { @@ -68,7 +68,7 @@ public Service service() { @Bean public RetryListener listener() { - return new RetryListenerSupport() { + return new RetryListener() { @Override public void close(RetryContext context, RetryCallback callback, Throwable throwable) { @@ -94,7 +94,7 @@ public ServiceWithOverriddenListener service() { @Bean public RetryListener listener1() { - return new RetryListenerSupport() { + return new RetryListener() { @Override public void close(RetryContext context, RetryCallback callback, Throwable throwable) { @@ -105,7 +105,7 @@ public void close(RetryContext context, RetryCallback void close(RetryContext context, RetryCallback callback, Throwable throwable) { diff --git a/src/test/java/org/springframework/retry/interceptor/RetryOperationsInterceptorTests.java b/src/test/java/org/springframework/retry/interceptor/RetryOperationsInterceptorTests.java index 21ea13dd..60717004 100644 --- a/src/test/java/org/springframework/retry/interceptor/RetryOperationsInterceptorTests.java +++ b/src/test/java/org/springframework/retry/interceptor/RetryOperationsInterceptorTests.java @@ -35,8 +35,8 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.retry.RetryCallback; import org.springframework.retry.RetryContext; +import org.springframework.retry.RetryListener; import org.springframework.retry.listener.MethodInvocationRetryListenerSupport; -import org.springframework.retry.listener.RetryListenerSupport; import org.springframework.retry.policy.NeverRetryPolicy; import org.springframework.retry.policy.SimpleRetryPolicy; import org.springframework.retry.support.RetryTemplate; @@ -47,6 +47,13 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +/** + * @author Dave Syer + * @author Marius Grama + * @author Gary Russell + * @author Stéphane Nicoll + * @author Henning Pöttker + */ public class RetryOperationsInterceptorTests { private static int count; @@ -66,7 +73,7 @@ public void setUp() { this.interceptor = new RetryOperationsInterceptor(); RetryTemplate retryTemplate = new RetryTemplate(); final AtomicBoolean calledFirst = new AtomicBoolean(); - retryTemplate.registerListener(new RetryListenerSupport() { + retryTemplate.registerListener(new RetryListener() { @Override public boolean open(RetryContext context, RetryCallback callback) { @@ -83,7 +90,7 @@ public void close(RetryContext context, RetryCallback boolean open(RetryContext context, RetryCallback callback) { diff --git a/src/test/java/org/springframework/retry/interceptor/StatefulRetryOperationsInterceptorTests.java b/src/test/java/org/springframework/retry/interceptor/StatefulRetryOperationsInterceptorTests.java index 01b0ab4c..5c266b8d 100644 --- a/src/test/java/org/springframework/retry/interceptor/StatefulRetryOperationsInterceptorTests.java +++ b/src/test/java/org/springframework/retry/interceptor/StatefulRetryOperationsInterceptorTests.java @@ -32,8 +32,8 @@ import org.springframework.retry.ExhaustedRetryException; import org.springframework.retry.RetryCallback; import org.springframework.retry.RetryContext; +import org.springframework.retry.RetryListener; import org.springframework.retry.RetryOperations; -import org.springframework.retry.listener.RetryListenerSupport; import org.springframework.retry.policy.AlwaysRetryPolicy; import org.springframework.retry.policy.NeverRetryPolicy; import org.springframework.retry.policy.SimpleRetryPolicy; @@ -51,6 +51,7 @@ /** * @author Dave Syer * @author Gary Russell + * @author Henning Pöttker * */ public class StatefulRetryOperationsInterceptorTests { @@ -70,7 +71,7 @@ public class StatefulRetryOperationsInterceptorTests { @BeforeEach public void setUp() { interceptor = new StatefulRetryOperationsInterceptor(); - retryTemplate.registerListener(new RetryListenerSupport() { + retryTemplate.registerListener(new RetryListener() { @Override public void close(RetryContext context, RetryCallback callback, Throwable throwable) { diff --git a/src/test/java/org/springframework/retry/listener/RetryListenerSupportTests.java b/src/test/java/org/springframework/retry/listener/RetryListenerSupportTests.java index b5835638..a2f2cbd4 100644 --- a/src/test/java/org/springframework/retry/listener/RetryListenerSupportTests.java +++ b/src/test/java/org/springframework/retry/listener/RetryListenerSupportTests.java @@ -21,6 +21,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatNoException; +/** + * @author Dave Syer + * @author Gary Russell + * @author Henning Pöttker + */ +@SuppressWarnings("deprecation") public class RetryListenerSupportTests { @Test diff --git a/src/test/java/org/springframework/retry/listener/RetryListenerTests.java b/src/test/java/org/springframework/retry/listener/RetryListenerTests.java index 8f9fd8e3..b1957924 100644 --- a/src/test/java/org/springframework/retry/listener/RetryListenerTests.java +++ b/src/test/java/org/springframework/retry/listener/RetryListenerTests.java @@ -31,7 +31,14 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.assertj.core.api.Assertions.assertThatNoException; +/** + * @author Dave Syer + * @author Stéphane Nicoll + * @author Gary Russell + * @author Henning Pöttker + */ public class RetryListenerTests { RetryTemplate template = new RetryTemplate(); @@ -40,15 +47,43 @@ public class RetryListenerTests { List list = new ArrayList<>(); + @Test + public void testOpenDefaultImplementation() { + var retryListener = new RetryListener() { + }; + assertThat(retryListener.open(null, null)).isTrue(); + } + + @Test + public void testCloseDefaultImplementation() { + var retryListener = new RetryListener() { + }; + assertThatNoException().isThrownBy(() -> retryListener.close(null, null, null)); + } + + @Test + public void testOnSuccessDefaultImplementation() { + var retryListener = new RetryListener() { + }; + assertThatNoException().isThrownBy(() -> retryListener.onError(null, null, null)); + } + + @Test + public void testOnErrorDefaultImplementation() { + var retryListener = new RetryListener() { + }; + assertThatNoException().isThrownBy(() -> retryListener.onError(null, null, null)); + } + @Test public void testOpenInterceptors() { - template.setListeners(new RetryListener[] { new RetryListenerSupport() { + template.setListeners(new RetryListener[] { new RetryListener() { public boolean open(RetryContext context, RetryCallback callback) { count++; list.add("1:" + count); return true; } - }, new RetryListenerSupport() { + }, new RetryListener() { public boolean open(RetryContext context, RetryCallback callback) { count++; list.add("2:" + count); @@ -63,7 +98,7 @@ public boolean open(RetryContext context, RetryCallback @Test public void testOpenCanVetoRetry() { - template.registerListener(new RetryListenerSupport() { + template.registerListener(new RetryListener() { public boolean open(RetryContext context, RetryCallback callback) { list.add("1"); return false; @@ -80,13 +115,13 @@ public boolean open(RetryContext context, RetryCallback @Test public void testCloseInterceptors() { - template.setListeners(new RetryListener[] { new RetryListenerSupport() { + template.setListeners(new RetryListener[] { new RetryListener() { public void close(RetryContext context, RetryCallback callback, Throwable t) { count++; list.add("1:" + count); } - }, new RetryListenerSupport() { + }, new RetryListener() { public void close(RetryContext context, RetryCallback callback, Throwable t) { count++; @@ -103,12 +138,12 @@ public void close(RetryContext context, RetryCallback void onError(RetryContext context, RetryCallback callback, Throwable throwable) { list.add("1"); } - }, new RetryListenerSupport() { + }, new RetryListener() { public void onError(RetryContext context, RetryCallback callback, Throwable throwable) { list.add("2"); @@ -128,7 +163,7 @@ public void onError(RetryContext context, RetryCallback @Test public void testCloseInterceptorsAfterRetry() { - template.registerListener(new RetryListenerSupport() { + template.registerListener(new RetryListener() { public void close(RetryContext context, RetryCallback callback, Throwable t) { list.add("" + count); diff --git a/src/test/java/org/springframework/retry/stats/StatisticsListenerTests.java b/src/test/java/org/springframework/retry/stats/StatisticsListenerTests.java index 4bfe0059..9f0b85b6 100644 --- a/src/test/java/org/springframework/retry/stats/StatisticsListenerTests.java +++ b/src/test/java/org/springframework/retry/stats/StatisticsListenerTests.java @@ -20,9 +20,9 @@ import org.springframework.retry.RetryCallback; import org.springframework.retry.RetryContext; +import org.springframework.retry.RetryListener; import org.springframework.retry.RetryState; import org.springframework.retry.RetryStatistics; -import org.springframework.retry.listener.RetryListenerSupport; import org.springframework.retry.policy.SimpleRetryPolicy; import org.springframework.retry.support.DefaultRetryState; import org.springframework.retry.support.RetryTemplate; @@ -31,6 +31,7 @@ /** * @author Dave Syer + * @author Henning Pöttker * */ public class StatisticsListenerTests { @@ -42,7 +43,7 @@ public class StatisticsListenerTests { @Test public void testStatelessSuccessful() throws Throwable { RetryTemplate retryTemplate = new RetryTemplate(); - retryTemplate.setListeners(new RetryListenerSupport[] { listener }); + retryTemplate.setListeners(new RetryListener[] { listener }); for (int x = 1; x <= 10; x++) { MockRetryCallback callback = new MockRetryCallback(); callback.setAttemptsBeforeSuccess(x); @@ -61,7 +62,7 @@ public void testStatelessSuccessful() throws Throwable { @Test public void testStatefulSuccessful() { RetryTemplate retryTemplate = new RetryTemplate(); - retryTemplate.setListeners(new RetryListenerSupport[] { listener }); + retryTemplate.setListeners(new RetryListener[] { listener }); RetryState state = new DefaultRetryState("foo"); for (int x = 1; x <= 10; x++) { MockRetryCallback callback = new MockRetryCallback(); @@ -88,7 +89,7 @@ public void testStatefulSuccessful() { @Test public void testStatelessUnsuccessful() { RetryTemplate retryTemplate = new RetryTemplate(); - retryTemplate.setListeners(new RetryListenerSupport[] { listener }); + retryTemplate.setListeners(new RetryListener[] { listener }); for (int x = 1; x <= 10; x++) { MockRetryCallback callback = new MockRetryCallback(); callback.setAttemptsBeforeSuccess(x + 1); @@ -111,7 +112,7 @@ public void testStatelessUnsuccessful() { @Test public void testStatefulUnsuccessful() { RetryTemplate retryTemplate = new RetryTemplate(); - retryTemplate.setListeners(new RetryListenerSupport[] { listener }); + retryTemplate.setListeners(new RetryListener[] { listener }); RetryState state = new DefaultRetryState("foo"); for (int x = 1; x <= 10; x++) { MockRetryCallback callback = new MockRetryCallback(); @@ -138,7 +139,7 @@ public void testStatefulUnsuccessful() { @Test public void testStatelessRecovery() throws Throwable { RetryTemplate retryTemplate = new RetryTemplate(); - retryTemplate.setListeners(new RetryListenerSupport[] { listener }); + retryTemplate.setListeners(new RetryListener[] { listener }); for (int x = 1; x <= 10; x++) { MockRetryCallback callback = new MockRetryCallback(); callback.setAttemptsBeforeSuccess(x + 1); @@ -157,7 +158,7 @@ public void testStatelessRecovery() throws Throwable { @Test public void testStatefulRecovery() { RetryTemplate retryTemplate = new RetryTemplate(); - retryTemplate.setListeners(new RetryListenerSupport[] { listener }); + retryTemplate.setListeners(new RetryListener[] { listener }); RetryState state = new DefaultRetryState("foo"); for (int x = 1; x <= 10; x++) { MockRetryCallback callback = new MockRetryCallback(); diff --git a/src/test/java/org/springframework/retry/support/RetryTemplateTests.java b/src/test/java/org/springframework/retry/support/RetryTemplateTests.java index 57cf9423..478b0478 100644 --- a/src/test/java/org/springframework/retry/support/RetryTemplateTests.java +++ b/src/test/java/org/springframework/retry/support/RetryTemplateTests.java @@ -25,12 +25,12 @@ import org.springframework.classify.BinaryExceptionClassifier; import org.springframework.retry.RetryCallback; import org.springframework.retry.RetryContext; +import org.springframework.retry.RetryListener; import org.springframework.retry.TerminatedRetryException; import org.springframework.retry.backoff.BackOffContext; import org.springframework.retry.backoff.BackOffInterruptedException; import org.springframework.retry.backoff.BackOffPolicy; import org.springframework.retry.backoff.StatelessBackOffPolicy; -import org.springframework.retry.listener.RetryListenerSupport; import org.springframework.retry.policy.NeverRetryPolicy; import org.springframework.retry.policy.SimpleRetryPolicy; @@ -48,6 +48,7 @@ * @author Rob Harrop * @author Dave Syer * @author Gary Russell + * @author Henning Pöttker */ public class RetryTemplateTests { @@ -311,7 +312,7 @@ public boolean rollbackFor(Throwable exception) { @Test public void testRetryOnBadResult() { RetryTemplate template = new RetryTemplate(); - template.registerListener(new RetryListenerSupport() { + template.registerListener(new RetryListener() { @Override public void onSuccess(RetryContext context, RetryCallback callback,