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)值機(jī)制虐先,無論要傳入任何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)類型對象的機(jī)制。這對于retry需要的異常類的轉(zhuǎn)換十分重要埠对,通常我們只需要定義某一類的異常重試策略络断,那么其子類異常也會同樣應(yīng)用到該策略,比如我們定義了數(shù)據(jù)庫錯誤SQLException需要重試项玛,實際運(yùn)行可能拋出的是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)計機(jī)制上。監(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)異常,而又會重試的情況下的補(bǔ)償機(jī)制(通常就是延時)。
BackOff.png
  1. BackOffPolicy接口:
    該包的核心接口菇怀,包含兩個方法凭舶,意識生成一個當(dāng)前補(bǔ)償上下文環(huán)境,二是進(jìn)行補(bǔ)償動作爱沟。
    //根據(jù)重試上下文生成一個補(bǔ)償上下文
    BackOffContext start(RetryContext context);
    //根據(jù)補(bǔ)償上下文執(zhí)行延遲操作帅霜,可能拋出中斷異常
    void backOff(BackOffContext backOffContext) throws BackOffInterruptedException;
  1. Sleeper接口與ThreadWaitSleeper類:
    真正的補(bǔ)償動作具體執(zhí)行器, ThreadWaitSleeper就是調(diào)用了Thread.sleep()方法進(jìn)行延遲呼伸。
  2. StatelessBackOffPolicy抽象類:
    其start方法返回null义屏,也就是沒有重試上下文,執(zhí)行backOff時候調(diào)用的是無參數(shù)的doBackOff()蜂大。換句話說闽铐,代表具體補(bǔ)償動作是固定的,并不依賴上下文環(huán)境奶浦。
  3. NoBackOffPolicy類:
    最簡單的默認(rèn)策略兄墅,具體延遲為空操作,也就是不補(bǔ)償澳叉,不延遲隙咸。
  4. SleepingBackOffPolicy接口:
    有一個withSleeper()方法,傳入一個Sleeper成洗。
  5. UniformRandomBackOffPolicy類:
    標(biāo)準(zhǔn)的隨機(jī)延遲策略五督,給定最小值,最大值(默認(rèn)為500L瓶殃,1500L)充包,會在這個區(qū)間里面隨機(jī)進(jìn)行補(bǔ)償延遲。
    7 FixedBackOffPolicy類:
    標(biāo)準(zhǔn)的固定延遲策略遥椿,每次延遲固定時間(默認(rèn)1000L)
  6. ExponentialBackOffPolicy類和ExponentialRandomBackOffPolicy:
    這兩個類都是SleepingBackOffPolicy的實現(xiàn)基矮,內(nèi)部用ThreadWaitSleeper延遲。實現(xiàn)的是延遲指數(shù)倍增的效果冠场,區(qū)別是ExponentialBackOffPolicy是固定倍增家浇,ExponentialRandomBackOffPolicy加入了隨機(jī)性。
    例如:
 * {@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. 擴(kuò)展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)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市娃肿,隨后出現(xiàn)的幾起案子咕缎,更是在濱河造成了極大的恐慌珠十,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凭豪,死亡現(xiàn)場離奇詭異焙蹭,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嫂伞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門孔厉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人帖努,你說我怎么就攤上這事撰豺。” “怎么了拼余?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵污桦,是天一觀的道長。 經(jīng)常有香客問我匙监,道長凡橱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任亭姥,我火速辦了婚禮稼钩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘达罗。我一直安慰自己坝撑,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布氮块。 她就那樣靜靜地躺著绍载,像睡著了一般。 火紅的嫁衣襯著肌膚如雪滔蝉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天塔沃,我揣著相機(jī)與錄音蝠引,去河邊找鬼。 笑死蛀柴,一個胖子當(dāng)著我的面吹牛螃概,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鸽疾,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼吊洼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了制肮?” 一聲冷哼從身側(cè)響起冒窍,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤递沪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后综液,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體款慨,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年谬莹,在試婚紗的時候發(fā)現(xiàn)自己被綠了檩奠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡附帽,死狀恐怖埠戳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蕉扮,我是刑警寧澤乞而,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站慢显,受9級特大地震影響爪模,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荚藻,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一屋灌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧应狱,春花似錦共郭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至岸蜗,卻和暖如春尉咕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背璃岳。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工年缎, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铃慷。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓单芜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親犁柜。 傳聞我的和親對象是個殘疾皇子洲鸠,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容

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