diff --git a/spring-all/pom.xml b/spring-all/pom.xml
index e77bf0b284..deb6bd6f6a 100644
--- a/spring-all/pom.xml
+++ b/spring-all/pom.xml
@@ -38,6 +38,11 @@
org.springframework
spring-context
+
+ org.springframework.retry
+ spring-retry
+ ${springretry.version}
+
@@ -166,7 +171,6 @@
ehcache
${ehcache.version}
-
@@ -275,6 +279,7 @@
4.3.4.RELEASE
4.2.0.RELEASE
+ 1.1.5.RELEASE
5.2.5.Final
diff --git a/spring-all/src/main/java/org/baeldung/springretry/AppConfig.java b/spring-all/src/main/java/org/baeldung/springretry/AppConfig.java
new file mode 100644
index 0000000000..63bb2a53f1
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/springretry/AppConfig.java
@@ -0,0 +1,34 @@
+package org.baeldung.springretry;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.retry.annotation.EnableRetry;
+import org.springframework.retry.backoff.FixedBackOffPolicy;
+import org.springframework.retry.policy.SimpleRetryPolicy;
+import org.springframework.retry.support.RetryTemplate;
+
+@Configuration
+@ComponentScan(basePackages = "org.baeldung.springretry")
+@EnableRetry
+//Uncomment this two lines if we need XML configuration
+//@EnableAspectJAutoProxy
+//@ImportResource("classpath:/retryadvice.xml")
+public class AppConfig {
+
+ @Bean
+ public RetryTemplate retryTemplate() {
+ RetryTemplate retryTemplate = new RetryTemplate();
+
+ FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
+ fixedBackOffPolicy.setBackOffPeriod(2000l);
+ retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
+
+ SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
+ retryPolicy.setMaxAttempts(2);
+ retryTemplate.setRetryPolicy(retryPolicy);
+
+ retryTemplate.registerListener(new DefaultListenerSupport());
+ return retryTemplate;
+ }
+}
diff --git a/spring-all/src/main/java/org/baeldung/springretry/DefaultListenerSupport.java b/spring-all/src/main/java/org/baeldung/springretry/DefaultListenerSupport.java
new file mode 100644
index 0000000000..bc251b4c2f
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/springretry/DefaultListenerSupport.java
@@ -0,0 +1,31 @@
+package org.baeldung.springretry;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.retry.RetryCallback;
+import org.springframework.retry.RetryContext;
+import org.springframework.retry.listener.RetryListenerSupport;
+
+public class DefaultListenerSupport extends RetryListenerSupport {
+
+ private static final Logger logger = LoggerFactory.getLogger(DefaultListenerSupport.class);
+
+ @Override
+ public void close(RetryContext context, RetryCallback callback, Throwable throwable) {
+ logger.info("onClose");
+ super.close(context, callback, throwable);
+ }
+
+ @Override
+ public void onError(RetryContext context, RetryCallback callback, Throwable throwable) {
+ logger.info("onError");
+ super.onError(context, callback, throwable);
+ }
+
+ @Override
+ public boolean open(RetryContext context, RetryCallback callback) {
+ logger.info("onOpen");
+ return super.open(context, callback);
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/springretry/MyService.java b/spring-all/src/main/java/org/baeldung/springretry/MyService.java
new file mode 100644
index 0000000000..2b8cc16eb3
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/springretry/MyService.java
@@ -0,0 +1,21 @@
+package org.baeldung.springretry;
+
+import java.sql.SQLException;
+
+import org.springframework.retry.annotation.Backoff;
+import org.springframework.retry.annotation.Recover;
+import org.springframework.retry.annotation.Retryable;
+
+public interface MyService {
+
+ @Retryable
+ void retryService();
+
+ @Retryable(value = { SQLException.class }, maxAttempts = 2, backoff = @Backoff(delay = 5000))
+ void retryServiceWithRecovery(String sql) throws SQLException;
+
+ @Recover
+ void recover(SQLException e, String sql);
+
+ void templateRetryService();
+}
diff --git a/spring-all/src/main/java/org/baeldung/springretry/MyServiceImpl.java b/spring-all/src/main/java/org/baeldung/springretry/MyServiceImpl.java
new file mode 100644
index 0000000000..1b698f26c9
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/springretry/MyServiceImpl.java
@@ -0,0 +1,39 @@
+package org.baeldung.springretry;
+
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+@Service
+public class MyServiceImpl implements MyService {
+
+ private static final Logger logger = LoggerFactory.getLogger(MyServiceImpl.class);
+
+ @Override
+ public void retryService() {
+ logger.info("throw RuntimeException in method retryService()");
+ throw new RuntimeException();
+ }
+
+ @Override
+ public void retryServiceWithRecovery(String sql) throws SQLException {
+ if (StringUtils.isEmpty(sql)) {
+ logger.info("throw SQLException in method retryServiceWithRecovery()");
+ throw new SQLException();
+ }
+ }
+
+ @Override
+ public void recover(SQLException e, String sql) {
+ logger.info("In recover method");
+ }
+
+ @Override
+ public void templateRetryService() {
+ logger.info("throw RuntimeException in method templateRetryService()");
+ throw new RuntimeException();
+ }
+}
diff --git a/spring-all/src/main/resources/retryadvice.xml b/spring-all/src/main/resources/retryadvice.xml
new file mode 100644
index 0000000000..8de7801a58
--- /dev/null
+++ b/spring-all/src/main/resources/retryadvice.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Initial sleep interval value, default 300 ms
+
+
+
+
+ The maximum value of the backoff period in milliseconds.
+
+
+
+
+ The value to increment the exp seed with for each retry attempt.
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-all/src/test/java/org/baeldung/springretry/SpringRetryTest.java b/spring-all/src/test/java/org/baeldung/springretry/SpringRetryTest.java
new file mode 100644
index 0000000000..52f59dc49a
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/springretry/SpringRetryTest.java
@@ -0,0 +1,45 @@
+package org.baeldung.springretry;
+
+import java.sql.SQLException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.retry.RetryCallback;
+import org.springframework.retry.RetryContext;
+import org.springframework.retry.support.RetryTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = AppConfig.class, loader = AnnotationConfigContextLoader.class)
+public class SpringRetryTest {
+
+ @Autowired
+ private MyService myService;
+
+ @Autowired
+ private RetryTemplate retryTemplate;
+
+ @Test(expected = RuntimeException.class)
+ public void givenRetryService_whenCallWithException_thenRetry() {
+ myService.retryService();
+ }
+
+ @Test
+ public void givenRetryServiceWithRecovery_whenCallWithException_thenRetryRecover() throws SQLException {
+ myService.retryServiceWithRecovery(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void givenTemplateRetryService_whenCallWithException_thenRetry() {
+ retryTemplate.execute(new RetryCallback() {
+ @Override
+ public Void doWithRetry(RetryContext arg0) {
+ myService.templateRetryService();
+ return null;
+ }
+ });
+ }
+}