spring-retry(2.源码查看classify包,retry接口、backoff 包)


classify

在spring-retry-××.jar的源码中,我们发现这个包里面还有一个和retry同级的classify包,显然它应该是retry需要用到,但是又不是包含的retry模型里面的东西。

spring-retry(2.源码查看classify包,retry接口、backoff 包)_第1张图片
classify.png

classify包作为retry的辅助类,主要应用于RetryPolicy的canRetry()方法中,通过比较捕获的异常与定义的异常直接关系,决定是否符合重试条件,其包结构类图如下:


spring-retry(2.源码查看classify包,retry接口、backoff 包)_第2张图片
Classifier.png
  1. Classifier 接口:
    是整个包的核心接口,定义了
T classify(C classifiable);

把一个C类型对象,转换为T类型对象,其中T类型通常是枚举类型或者布尔类型这种可以直接比较结果的。

  1. ClassifierSupport 类:
    一个基础实现,引入默认值机制,无论要传入任何C类型对象,都返回默认的T类型对象。
  2. ClassifierAdapter 类:
    定义了两种方式的转换,一种直接Classifier,在需要转换时候调用,
    一种传入通过识别一个目标类中@Classifier注解的方法,把它作为转换的实现类,在需要转换时候调用。
  3. SubclassClassifier类:
    首先要注意这里T和C对调写了,实现了能识别一个类和其子类都能被识别到,转换为目标类型对象的机制。这对于retry需要的异常类的转换十分重要,通常我们只需要定义某一类的异常重试策略,那么其子类异常也会同样应用到该策略,比如我们定义了数据库错误SQLException需要重试,实际运行可能抛出的是SQLTimeoutException,或者BatchUpdateException,它们就都会被捕获重试。
  4. BinaryExceptionClassifier类:
    明确化了SubclassClassifier的类型,其classify()方法把Throwable转换为Boolean。代码如下:
@Override
    public Boolean classify(Throwable classifiable) {
        Boolean classified = super.classify(classifiable);
        if (!this.traverseCauses) {
            return classified;
        }

        /*
         * If the result is the default, we need to find out if it was by default
         * or so configured; if default, try the cause(es).
         */
        if (classified.equals(this.getDefault())) {
            Throwable cause = classifiable;
            do {
                if (this.getClassified().containsKey(cause.getClass())) {
                    return classified; // non-default classification
                }
                cause = cause.getCause();
                classified = super.classify(cause);
            }
            while (cause != null && classified.equals(this.getDefault()));
        }

        return classified;
    }

如果traverseCauses为false,就简单调用父类进行转换即可,如果为真,就必须一直找Throwable的Cause链条,直到找到匹配的转换。
P.S. Traverse: 穿过、横贯

  1. PatternMatcher和PatternMatchingClassifier
    能够把符合样式的字符串转换为T对象的转换器。
    其核心方法为imatch(),对?和*进行了处理判断,判断输入的str是否符合某种样式pattern。
  2. BackToBackPatternClassifier 类:
    背对背映射组合,先吧C对象转换为string,然后再把string转换为T对象。

retry顶级接口

retry顶级接口定义了核心的概念,其相互关系如下:
spring-retry(2.源码查看classify包,retry接口、backoff 包)_第3张图片
retry.png

具体含义:请移步spring-retry(1.概念和基本用法),这里简要分析一些接口方法。

  1. RetryContext接口:
    从图上可以看到,重试上下文处于核心位置,作为核心数据接口,储存了重试所需要的各类信息。
RetryContext getParent();
从获取父上下文方法可知,它是一个链式结构。
  1. RetryPolicy接口:
    //判断一个上下文能否重试
    boolean canRetry(RetryContext context);
    //开启一个重试上下文环境
    RetryContext open(RetryContext parent);
    //关闭一个重试上下文环境
    void close(RetryContext context);
    //出现异常时候,把异常登记到上下文中
    void registerThrowable(RetryContext context, Throwable throwable);

从接口参数可以看出,策略都是根据上下文情况进行判断分析的。

  1. RetryOperations接口:
    各种花式execute(),根据可配置的重试行为,进行方法的执行,其具体的实现就是核心类RetryTemplate
  2. RetryListener接口:
    作为重试动作的监听器,给spring-retry加点料,用在统计机制上。监听3类动作:open()在开启操作之前,close()在关闭操作之后,onError()在出现错误时。
  3. RetryStatistics接口:
    记录重试统计信息的接口。登记完成数、开始数、错误数、中止数、恢复数。
  4. RetryException及ExhaustedRetryException,TerminatedRetryException异常
    定义了retry项目内部可能抛出的异常,RetryException是基类。
    Exhausted:精疲力竭的
    Terminated:终止的

retry.backoff 包

该包定义了当出现异常,而又会重试的情况下的补偿机制(通常就是延时)。
spring-retry(2.源码查看classify包,retry接口、backoff 包)_第4张图片
BackOff.png
  1. BackOffPolicy接口:
    该包的核心接口,包含两个方法,意识生成一个当前补偿上下文环境,二是进行补偿动作。
    //根据重试上下文生成一个补偿上下文
    BackOffContext start(RetryContext context);
    //根据补偿上下文执行延迟操作,可能抛出中断异常
    void backOff(BackOffContext backOffContext) throws BackOffInterruptedException;
  1. Sleeper接口与ThreadWaitSleeper类:
    真正的补偿动作具体执行器, ThreadWaitSleeper就是调用了Thread.sleep()方法进行延迟。
  2. StatelessBackOffPolicy抽象类:
    其start方法返回null,也就是没有重试上下文,执行backOff时候调用的是无参数的doBackOff()。换句话说,代表具体补偿动作是固定的,并不依赖上下文环境。
  3. NoBackOffPolicy类:
    最简单的默认策略,具体延迟为空操作,也就是不补偿,不延迟。
  4. SleepingBackOffPolicy接口:
    有一个withSleeper()方法,传入一个Sleeper。
  5. UniformRandomBackOffPolicy类:
    标准的随机延迟策略,给定最小值,最大值(默认为500L,1500L),会在这个区间里面随机进行补偿延迟。
    7 FixedBackOffPolicy类:
    标准的固定延迟策略,每次延迟固定时间(默认1000L)
  6. ExponentialBackOffPolicy类和ExponentialRandomBackOffPolicy:
    这两个类都是SleepingBackOffPolicy的实现,内部用ThreadWaitSleeper延迟。实现的是延迟指数倍增的效果,区别是ExponentialBackOffPolicy是固定倍增,ExponentialRandomBackOffPolicy加入了随机性。
    例如:
 * {@link ExponentialBackOffPolicy} 延迟序列为: [50, 100, 200, 400, 800]
 *
 * {@link ExponentialRandomBackOffPolicy} 延迟序列可能为: [76, 151, 304, 580, 901] 或者 [53, 190,
 * 267, 451, 815]

retry.context 包

该包只有一个类RetryContextSupport,重试上下文的具体实现。

  1. 扩展AttributeAccessorSupport:内部有个linkedHashMap存储标准属性外的其他属性
  2. 有parent属性,在构造时候传入其父上下文,这样就维护了一个链表信息,方便后续查找。
  3. count和lastException是记录型属性,登记这个上下文的状态。

你可能感兴趣的:(spring-retry(2.源码查看classify包,retry接口、backoff 包))