Tag: Spring

SPRING RETRY FRAMEWORK FOR BETTER JAVA DEVELOPMENT

In this article, you will get knowledge about the Spring Retry framework. Professionals of Java development company have introduced this technology and shared their top knowledge for the same. You can read this article and obtain how they use this technology.

Technology: Spring Retry is the framework to support retries support for spring-based applications in a declarative way. This framework immediately recreates the method for booming operation for specified attempts, this framework also supports after the many times attempts we can define the fallback method so that it will be executed.

Whenever software applications communicate with each other there is a chance of temporary self-correcting faults, like unavailability of services, temporary loss of network, or request timeouts because of server busy, in these cases, we can use another implement so that problems can be decreased.

Setup:

To use Spring Retry we need to add the below dependency.

<dependency>
<groupid>org.springframework.retry</groupid>
<artifactid>spring-retry</artifactid>
<version>1.1.2.RELEASE</version>
</dependency>

Spring Retry uses Spring AOP, we need to add Spring AOP dependency to the classpath.

<dependency>
  <groupid>org.springframework</groupid>
  <artifactid>spring-aop</artifactid>
  <version>4.2.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.8.8</version>
</dependency>

If we are utilizing spring boot then we require to use then we can add the spring boot app as a dependency.

<dependency>
  <groupid>org.springframework.boot</groupid>
  <artifactid>spring-boot-starter-aop</artifactid>
</dependency>

Enable Spring retry in spring based applications:

Spring Retry provides @EnableRetry annotation to bootstrap the framework. We need to add this annotation on any one of the @Configuration annotated classes.

This framework was developed using spring AOP proxies. In spring AOP supports two types of proxies, JDK dynamic proxies, and CGLIB proxies.

@EnableRetry provides one attribute proxy target class to specify either to use CGLIB proxy or JDK dynamic proxy.

Adding spring retry annotation to spring classes:

We can add @Retry annotation to any method that we want to repeat the method if any exception occurs during the execution.

We can customize the re-try configuration using annotation attributes.

•    Include: accepts comma-separated exceptions, for which exceptions this method has to invoke.

•    Interceptor: Try again the interceptor bean name to be applied for the retryable method.

•    Value: Exception types that are retryable. Synonym for includes(). Defaults to empty (and if excludes is also empty all exceptions are retried).

•    Exclude: Exception types that are not again triable. Defaults to empty (and if includes is also empty all exceptions are retried).

    Stateful: Flag to represent the retry is stateful: i.e. exceptions are again thrown, but the retry policy is applied with the same policy to the next invitation with the same arguments. If false then retriable exceptions are not again thrown. The default is value.

•    Max attempts: the maximum number of attempts (including the first failure), the default value is 3

•    Backoff: define the backoff properties to try again this operation. The default is no backoff.

BackOff attribute is used to provide inputs to retry operations like specifying delay, max-delay, etc… using @backoff annotation.

Example:

@Retryable(value = {SampleException.class, SimpleException.class}, maxAttempts = 5)
publicvoidretryWithException() {
System.out.println("retryWithException");
thrownewSampleException("exception in retry annotate method");
    }

@Recover: we can annotate any method with this annotation to mark it as a recovery method for retry operations. Recovery handler methods need to have the first argument of type Throwable (or any subtype of Throwable) and the return type of this method must be the same as the return type of @Retryable to the method. The Throwable first argument is optional (but it will be called only if none of the recovery methods matches), and the subsequent arguments are populated from the @Retryable method.

Example:

@Recover
publicvoid recover(SampleExceptionexception) {
System.out.println("recovering from SampleException ->" + exception.getMessage());
    }

Some of the most useful Classes in the spring retry framework:

RetryTemplate: To make it robust and less error-prone to failure sometimes we need to retry failed operations on a subsequent attempt. For example, a remote call to web service that fails on network failures or deadlock situation which may be resolved after a short wait, to automate the retry of such operations springRetry has a strategy RetryOperations strategy.

The RetryOperation will look like this:

public interface RetryOperations {
    <T, E extends Throwable> T execute(RetryCallback<T, E>retryCallback) throws E;
    <T, E extends Throwable> T execute(RetryCallback<T, E>retryCallback, RecoveryCallback<T>recoveryCallback) throws E;
    <T, E extends Throwable> T execute(RetryCallback<T, E>retryCallback, RetryStateretryState) throws E, ExhaustedRetryException;
    <T, E extends Throwable> T execute(RetryCallback<T, E>retryCallback, RecoveryCallback<T>recoveryCallback, RetryStateretryState) throws E;
}

And the retrycallback will look like this:

public interface RetryCallback<T, E extends Throwable> {
    T doWithRetry(RetryContext context) throws E;
}

This is a basic callback to insert some business logic to retry the operation.

The callback is performed and if it fails (by throwing an Exception), it will be tried again until either it is successful, or the execution decides to abort. There are a number of overloaded performance methods in the RetryOperations interface dealing with several use cases for recovery when all try again attempts are exhausted, and also with try again state, which permits customers and implementations to store information between calls.

For example, for timeout retry operations spring retry framework has a TimeoutRetryPolicy policy.

We can add this retry policy in the retry template so that it will be retried until timeout for a successful response.

RetryTemplateretryTemplate = new RetryTemplate();
TimeoutRetryPolicyretryPolicy = new TimeoutRetryPolicy();
retryPolicy.setTimeout(1000L);
retryTemplate.setRetryPolicy(retryPolicy);
retryTemplate.execute(new RetryCallback<HelloWorld, Exception>() {
    @Override
    public HelloWorld doWithRetry(RetryContext context) throws Exception {
        return result;
    }
});

The above example executes a web service call and returns the result to the user, if that fails then it is retried until the timeout is reached.

RetryContext: The method argument for the RetryCallback is a RetryContext.It is used as an attribute bag to store data for the duration of the iteration.ARetryContext will have a parent context if there is a fixed retry in progress in the same thread. The parent context is sometimes useful for holding data that need to be shared between calls to execute.

RecoveryCallback: It is the callback interface if all configured retry policies are executed but don`t receive a successful response.

Listeners: Spring retry provides a RetryListener interface for cross-cutting features in retry operations; RetryTemplate provides a way to attach a listener to it so that it will be called in respected operations.

The RetryListener interface will look like this:

public interface RetryListener {
    <T, E extends Throwable>booleanopen(RetryContext context, RetryCallback<T, E> callback);
    <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwablethrowable);
    <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwablethrowable);
}

Open and close methods will be performed before and after the whole retry operation, and the onError method is performed on all individual callback, the close method might also receive a Throwable, if there is an error it is the last one thrown by the RetryCallback.

If more than one listener is configured, there must be some order of execution of listener, open method is executed in the same order as configured, and onErrror and close method will be called in reverse order.

The sample RetryTemplate will be:

publicRetryTemplateretryTemplate() {
SimpleRetryPolicyretryPolicy = newSimpleRetryPolicy();
retryPolicy.setMaxAttempts(5);
 
FixedBackOffPolicybackOffPolicy = newFixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(1500); // 1.5 seconds
 
RetryTemplatetemplate = newRetryTemplate();
template.setRetryPolicy(retryPolicy);
template.setBackOffPolicy(backOffPolicy);
 
RetryListener[] listeners = newRetryListener[2];
listeners[0] = newSampleRetryListener();
listeners[1] = newSimpleRetryListener();
        template.setListeners(listeners);
        
returntemplate;
    }

Conclusion:

Spring Retry is the framework for declarative using @Retryable and @Recover, and programmatic way using RetryCallback and RecoveryCallBack to support retry operations in spring-based applications, this framework also supports cross-cutting using retry listeners.

Source code can be downloaded at: https://github.com/sravan4rmhyd/SpringRetryDemo.git

So, you now know the Spring Retry technology. If you have any questions, ask experts of Java development company straightforward in the comments. Do share your feedback for this post and tell other readers what your experience with this framework was.

Related Article:

Java Developers Sharing Node.Js Performance Tips For Adoption

Exploring The Java Platform Through Best Java Jobs