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


classify

在spring-retry-××.jar的源碼中,我們發(fā)現(xiàn)這個包里面還有一個和retry同級的classify包,顯然它應(yīng)該是retry需要用到,但是又不是包含的retry模型里面的東西。

classify.png

classify包作為retry的輔助類,主要應(yīng)用于RetryPolicy的canRetry()方法中,通過比較捕獲的異常與定義的異常直接關(guān)系,決定是否符合重試條件,其包結(jié)構(gòu)類圖如下:


Classifier.png
  1. Classifier<C, T> 接口:
    是整個包的核心接口,定義了
T classify(C classifiable);

把一個C類型對象,轉(zhuǎn)換為T類型對象,其中T類型通常是枚舉類型或者布爾類型這種可以直接比較結(jié)果的。

  1. ClassifierSupport<C, T> 類:
    一個基礎(chǔ)實現(xiàn),引入默認(rèn)值機制,無論要傳入任何C類型對象,都返回默認(rèn)的T類型對象。
  2. ClassifierAdapter<C, T> 類:
    定義了兩種方式的轉(zhuǎn)換,一種直接Classifier,在需要轉(zhuǎn)換時候調(diào)用,
    一種傳入通過識別一個目標(biāo)類中@Classifier注解的方法,把它作為轉(zhuǎn)換的實現(xiàn)類,在需要轉(zhuǎn)換時候調(diào)用。
  3. SubclassClassifier<T, C>類:
    首先要注意這里T和C對調(diào)寫了,實現(xiàn)了能識別一個類和其子類都能被識別到,轉(zhuǎn)換為目標(biāo)類型對象的機制。這對于retry需要的異常類的轉(zhuǎn)換十分重要,通常我們只需要定義某一類的異常重試策略,那么其子類異常也會同樣應(yīng)用到該策略,比如我們定義了數(shù)據(jù)庫錯誤SQLException需要重試,實際運行可能拋出的是SQLTimeoutException,或者BatchUpdateException,它們就都會被捕獲重試。
  4. BinaryExceptionClassifier類:
    明確化了SubclassClassifier<T, C>的類型,其classify()方法把Throwable轉(zhuǎn)換為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,就簡單調(diào)用父類進(jìn)行轉(zhuǎn)換即可,如果為真,就必須一直找Throwable的Cause鏈條,直到找到匹配的轉(zhuǎn)換。
P.S. Traverse: 穿過、橫貫

  1. PatternMatcher和PatternMatchingClassifier<T> :
    能夠把符合樣式的字符串轉(zhuǎn)換為T對象的轉(zhuǎn)換器。
    其核心方法為imatch(),對?和*進(jìn)行了處理判斷,判斷輸入的str是否符合某種樣式pattern。
  2. BackToBackPatternClassifier<C, T> 類:
    背對背映射組合,先吧C對象轉(zhuǎn)換為string,然后再把string轉(zhuǎn)換為T對象。

retry頂級接口

retry頂級接口定義了核心的概念,其相互關(guān)系如下:
retry.png

具體含義:請移步spring-retry(1.概念和基本用法),這里簡要分析一些接口方法。

  1. RetryContext接口:
    從圖上可以看到,重試上下文處于核心位置,作為核心數(shù)據(jù)接口,儲存了重試所需要的各類信息。
RetryContext getParent();
從獲取父上下文方法可知,它是一個鏈?zhǔn)浇Y(jié)構(gòu)。
  1. RetryPolicy接口:
    //判斷一個上下文能否重試
    boolean canRetry(RetryContext context);
    //開啟一個重試上下文環(huán)境
    RetryContext open(RetryContext parent);
    //關(guān)閉一個重試上下文環(huán)境
    void close(RetryContext context);
    //出現(xiàn)異常時候,把異常登記到上下文中
    void registerThrowable(RetryContext context, Throwable throwable);

從接口參數(shù)可以看出,策略都是根據(jù)上下文情況進(jìn)行判斷分析的。

  1. RetryOperations接口:
    各種花式execute(),根據(jù)可配置的重試行為,進(jìn)行方法的執(zhí)行,其具體的實現(xiàn)就是核心類RetryTemplate
  2. RetryListener接口:
    作為重試動作的監(jiān)聽器,給spring-retry加點料,用在統(tǒng)計機制上。監(jiān)聽3類動作:open()在開啟操作之前,close()在關(guān)閉操作之后,onError()在出現(xiàn)錯誤時。
  3. RetryStatistics接口:
    記錄重試統(tǒng)計信息的接口。登記完成數(shù)、開始數(shù)、錯誤數(shù)、中止數(shù)、恢復(fù)數(shù)。
  4. RetryException及ExhaustedRetryException,TerminatedRetryException異常
    定義了retry項目內(nèi)部可能拋出的異常,RetryException是基類。
    Exhausted:精疲力竭的
    Terminated:終止的

retry.backoff 包

該包定義了當(dāng)出現(xiàn)異常,而又會重試的情況下的補償機制(通常就是延時)。
BackOff.png
  1. BackOffPolicy接口:
    該包的核心接口,包含兩個方法,意識生成一個當(dāng)前補償上下文環(huán)境,二是進(jìn)行補償動作。
    //根據(jù)重試上下文生成一個補償上下文
    BackOffContext start(RetryContext context);
    //根據(jù)補償上下文執(zhí)行延遲操作,可能拋出中斷異常
    void backOff(BackOffContext backOffContext) throws BackOffInterruptedException;
  1. Sleeper接口與ThreadWaitSleeper類:
    真正的補償動作具體執(zhí)行器, ThreadWaitSleeper就是調(diào)用了Thread.sleep()方法進(jìn)行延遲。
  2. StatelessBackOffPolicy抽象類:
    其start方法返回null,也就是沒有重試上下文,執(zhí)行backOff時候調(diào)用的是無參數(shù)的doBackOff()。換句話說,代表具體補償動作是固定的,并不依賴上下文環(huán)境。
  3. NoBackOffPolicy類:
    最簡單的默認(rèn)策略,具體延遲為空操作,也就是不補償,不延遲。
  4. SleepingBackOffPolicy接口:
    有一個withSleeper()方法,傳入一個Sleeper。
  5. UniformRandomBackOffPolicy類:
    標(biāo)準(zhǔn)的隨機延遲策略,給定最小值,最大值(默認(rèn)為500L,1500L),會在這個區(qū)間里面隨機進(jìn)行補償延遲。
    7 FixedBackOffPolicy類:
    標(biāo)準(zhǔn)的固定延遲策略,每次延遲固定時間(默認(rèn)1000L)
  6. ExponentialBackOffPolicy類和ExponentialRandomBackOffPolicy:
    這兩個類都是SleepingBackOffPolicy的實現(xiàn),內(nèi)部用ThreadWaitSleeper延遲。實現(xiàn)的是延遲指數(shù)倍增的效果,區(qū)別是ExponentialBackOffPolicy是固定倍增,ExponentialRandomBackOffPolicy加入了隨機性。
    例如:
 * {@link ExponentialBackOffPolicy} 延遲序列為: [50, 100, 200, 400, 800]
 *
 * {@link ExponentialRandomBackOffPolicy} 延遲序列可能為: [76, 151, 304, 580, 901] 或者 [53, 190,
 * 267, 451, 815]

retry.context 包

該包只有一個類RetryContextSupport,重試上下文的具體實現(xiàn)。

  1. 擴展AttributeAccessorSupport:內(nèi)部有個linkedHashMap存儲標(biāo)準(zhǔn)屬性外的其他屬性
  2. 有parent屬性,在構(gòu)造時候傳入其父上下文,這樣就維護(hù)了一個鏈表信息,方便后續(xù)查找。
  3. count和lastException是記錄型屬性,登記這個上下文的狀態(tài)。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,715評論 19 139
  • http://liuxing.info/2017/06/30/Spring%20AMQP%E4%B8%AD%E6%...
    sherlock_6981閱讀 16,211評論 2 11
  • 前言 人生苦多,快來 Kotlin ,快速學(xué)習(xí)Kotlin! 什么是Kotlin? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,762評論 9 118
  • “你會理解心理治療的首要之務(wù),不是去強迫人改變他們的念頭;相反的,你要跟隨他們的念頭,用緩慢的步調(diào)來改變它,創(chuàng)造出...
    膩蟲閱讀 616評論 2 5
  • 人生就像一場夢,活著活著就死了。 是啊,人生如夢。 他們在豐富多彩的日子里翩翩起舞,你卻在為了了無生趣的生存煩煩惱...
    聲聲慢pan閱讀 3,016評論 4 3

友情鏈接更多精彩內(nèi)容