review

We learned that earlier

Introduction to Sisyphus, a better Java retry framework

The story behind Sisyphus, a better Java retry framework

In this section, let’s take a look at Sisyphus function-based configuration and annotated configuration.

Functional configuration overview

For easier configuration, the Retryer class provides a lot of information that can be configured.

The default configuration

/** * Default configuration test */
public void defaultConfigTest(a) {
    Retryer.<String>newInstance()
            .condition(RetryConditions.hasExceptionCause())
            .retryWaitContext(RetryWaiter.<String>retryWait(NoRetryWait.class).context())
            .maxAttempt(3)
            .listen(RetryListens.noListen())
            .recover(Recovers.noRecover())
            .callable(new Callable<String>() {
                @Override
                public String call(a) throws Exception {
                    System.out.println("called...");
                    throw new RuntimeException();
                }
            }).retryCall();
}
Copy the code

Is equivalent to the following code:

public void helloTest(a) {
    Retryer.<String>newInstance()
            .callable(new Callable<String>() {
                @Override
                public String call(a) throws Exception {
                    System.out.println("called...");
                    throw new RuntimeException();
                }
            }).retryCall();
}
Copy the code

Method statement

condition

Conditions for retry triggering. More than one condition can be specified.

The default is to throw an exception.

retryWaitContext

Multiple retry wait policies can be specified.

By default, no wait is performed.

maxAttempt

Specifies the maximum number of retries, including the first one.

Default value: 3

listen

Specifies a listening implementation for retry. Default is no listening.

recover

If the retry conditions are still met, you can specify a recovery policy.

No recovery is performed by default.

callable

Method to be retried.

retryCall

Retry execution is triggered.

This section describes interface details

Interfaces and their implementation

For all interfaces, you can directly view the corresponding subclass instance.

User defined

With the flexibility of substitution, users can implement interfaces and define implementations that are more relevant to their business.

Sisyphus annotations

Configurations are very flexible, but not as simple and flexible as annotations for use by developers.

So this framework also implements annotation-based retry.

Design specification

Ensure consistency between interfaces and annotations.

Maven is introduced into

<dependency>
    <groupId>${project.groupId}</groupId>
    <artifactId>sisyphus-annotation</artifactId>
    <version>${project.version}</version>
</dependency>
Copy the code

annotations

There are two main core annotations.

Retry

Used to specify configurations related to retry.

/** ** retry comments * 1. * 2. If placed on an interface, do all subclasses take effect? For simplicity, this implementation is not provided. * 3. Keep annotations and interfaces consistent. {@linkCom. Making. Houbb. Sisyphus. API. Core. Retry *} interface@author binbin.hou
 * @since0.0.3 * /
@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@RetryAble(DefaultRetryAbleHandler.class)
public @interface Retry {

    /** * Retry class implementation *@returnTry again *@since0.0.5 * /
    Class<? extends com.github.houbb.sisyphus.api.core.Retry> retry() default DefaultRetry.class;

    /** * Maximum number of attempts * 1. The number of times the method is normally executed for the first time *@returnThe number of * /
    int maxAttempt(a) default 3;

    /** * Retry the triggering scenario *@returnRetry the triggered scenario */
    Class<? extends RetryCondition> condition() default ExceptionCauseRetryCondition.class;

    /** * listener * 1. Default does not listen *@returnListener * /
    Class<? extends RetryListen> listen() default NoRetryListen.class;

    /** * Recovery operation * 1. No recovery operation is performed by default *@returnRestore the corresponding class */ for the operation
    Class<? extends Recover> recover() default NoRecover.class;

    /** * Wait policy * 1. Multiple wait policies can be specified. If no wait policy is specified, no wait is performed@returnWait policy */
    RetryWait[] waits() default {};

}
Copy the code

RetryWait

Used to specify the wait policy for retry.

package com.github.houbb.sisyphus.annotation.annotation;

import com.github.houbb.sisyphus.annotation.annotation.metadata.RetryWaitAble;
import com.github.houbb.sisyphus.annotation.handler.impl.DefaultRetryWaitAbleHandler;
import com.github.houbb.sisyphus.core.constant.RetryWaitConst;
import com.github.houbb.sisyphus.core.support.wait.NoRetryWait;

import java.lang.annotation.*;

1. To correspond to the retry policy, all built-in annotations should implement the current annotation. * 2. Are custom annotations allowed? * * When annotations + objects occur together, they are considered a combination. * *@author binbin.hou
 * @since0.0.3 * /
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Target(ElementType.ANNOTATION_TYPE)
@RetryWaitAble(DefaultRetryWaitAbleHandler.class)
public @interface RetryWait {

    /** * Default value * 1. Fixed mode, which corresponds to the fixed wait time * 2. Increasing *@returnThe default value * /
    long value(a) default RetryWaitConst.VALUE_MILLS;

    /** * minimum *@returnThe minimum * /
    long min(a) default RetryWaitConst.MIN_MILLS;

    /** * maximum value *@returnThe maximum * /
    long max(a) default RetryWaitConst.MAX_MILLS;

    /** * impact factor * 1. Incremental retry, default {@linkRetryWaitConst#INCREASE_MILLS_FACTOR} * 2. Exponential mode. The default is {@link RetryWaitConst#MULTIPLY_FACTOR}
     * @returnInfluence factor */
    double factor(a) default Double.MIN_VALUE;

    /** * Specifies the wait time for retry class information *@returnRetry wait time class */
    Class<? extends com.github.houbb.sisyphus.api.support.wait.RetryWait> retryWait() default NoRetryWait.class;

}
Copy the code

Use of annotations

Once annotations are defined, they must be used in conjunction with them.

There are two main ways to use annotations.

Proxy+CGLIB

Based on proxy mode and bytecode enhancement.

If you are not using Spring in your project, it is convenient to use this approach directly.

Spring-AOP

Can be directly integrated with Spring.

It is used in the same way as Spring-Retry.

These will be covered in detail in the next section.

summary

Flexible configuration can be more in line with the actual production and use of various needs.

Generally, it is recommended to use annotations for configuration, which is very simple and convenient.

Java Retry framework Sisyphus open source address

I hope this article is helpful to you. If you like it, please click to collect and forward a wave.

I am old ma, looking forward to meeting with you next time.