Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Retry Framework with Annotation not Working

I tried spring retry framework with Simple java classes using SimpleRetryPolicy/RetryTemplate. It worked fine. So I thought of doing the same with Annotations. Annotations never worked for me. Didn't find much help online as well. The following code just worked like normal Java program throwing the exception at first attempt which is not the expected behavior. It should have tried atleast 5 times before throwing exception or recovering from it. Not sure where I went wrong. Do I need to do any XML/spring AOP configuration for this to work ? How would that be

import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;

@EnableRetry
@Configuration
public class App {  
    public static void main(String[] args) throws Exception {
        Parentservice p = new  SpringRetryWithHystrixService();
        String status = p.getStatus();
        System.out.println(status);
    }
}

import org.springframework.retry.annotation.Retryable;
public interface Parentservice {
    @Retryable(maxAttempts=5)
    String getStatus() throws Exception;
}


import org.springframework.retry.annotation.Recover;
public class SpringRetryWithHystrixService implements Parentservice{

    public static int i=0;

    public String getStatus() throws Exception{
        System.out.println("Attempt:"+i++);
        throw new NullPointerException();
    }

        @Recover
        public static String getRecoveryStatus(){
            return "Recovered from NullPointer Exception";
        }
    }

I tried @Retryable(maxAttempts=5) on the top of interface and implementation which didn't make any difference.

like image 490
karthik Avatar asked Oct 28 '16 15:10

karthik


People also ask

How do I enable retry in spring boot?

First, you need to enable Spring Retry. You can achieve this by adding the @EnableRetry annotation to your @SpringBootApplication or @Configuration class. You can now use @Retryable to annotate any method to be a candidate or retry and @Recover to specify fallback methods.

What is @retryable?

The @Recover annotation defines a separate recovery method when a @Retryable method fails with a specified exception. Consequently, if the retryServiceWithRecovery method keeps throwing an SqlException after three attempts, the recover() method will be called.

Is Spring retry a circuit breaker?

Spring Retry provides a circuit breaker implementation via a combination of it's CircuitBreakerRetryPolicy and a stateful retry. All circuit breakers created using Spring Retry will be created using the CircuitBreakerRetryPolicy and a DefaultRetryState .

Does spring retry block thread?

However, whenever the execution of a retryable method fails with an exception, Spring will automatically retry to call the method up to three times. By default Spring uses a 1 second delay between method calls. Please note that the calling thread blocks during retry handling.


1 Answers

Your application has to be managed by Spring, you can't just use new ...

Parentservice p = new  SpringRetryWithHystrixService();

Here's a Spring Boot app...

@SpringBootApplication
@EnableRetry
public class So40308025Application {

    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(So40308025Application.class, args);
        System.out.println(context.getBean(SpringRetryWithHystrixService.class).getStatus());
        context.close();
    }

}


@Component
public class SpringRetryWithHystrixService {

    public static int i = 0;

    @Retryable(maxAttempts = 5)
    public String getStatus() throws Exception {
        System.out.println("Attempt:" + i++);
        throw new NullPointerException();
    }

    @Recover
    public static String getRecoveryStatus() {
        return "Recovered from NullPointer Exception";
    }

}

result:

Attempt:0
Attempt:1
Attempt:2
Attempt:3
Attempt:4
Recovered from NullPointer Exception

If you don't want to use Spring Boot for some reason, use

@Configuration
@EnableRetry
public class So40308025Application {

    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(So40308025Application.class);
        System.out.println(context.getBean(SpringRetryWithHystrixService.class).getStatus());
        context.close();
    }

    @Bean
    public SpringRetryWithHystrixService service() {
        return new SpringRetryWithHystrixService();
    }

}
like image 105
Gary Russell Avatar answered Oct 16 '22 19:10

Gary Russell