classify
在spring-retry-××.jar的源碼中罢荡,我們發(fā)現(xiàn)這個包里面還有一個和retry同級的classify包赡突,顯然它應(yīng)該是retry需要用到,但是又不是包含的retry模型里面的東西区赵。
classify包作為retry的輔助類惭缰,主要應(yīng)用于RetryPolicy的canRetry()方法中,通過比較捕獲的異常與定義的異常直接關(guān)系笼才,決定是否符合重試條件漱受,其包結(jié)構(gòu)類圖如下:
- Classifier<C, T> 接口:
是整個包的核心接口,定義了
T classify(C classifiable);
把一個C類型對象骡送,轉(zhuǎn)換為T類型對象昂羡,其中T類型通常是枚舉類型或者布爾類型這種可以直接比較結(jié)果的。
- ClassifierSupport<C, T> 類:
一個基礎(chǔ)實現(xiàn)摔踱,引入默認(rèn)值機(jī)制虐先,無論要傳入任何C類型對象,都返回默認(rèn)的T類型對象派敷。 - ClassifierAdapter<C, T> 類:
定義了兩種方式的轉(zhuǎn)換蛹批,一種直接Classifier,在需要轉(zhuǎn)換時候調(diào)用,
一種傳入通過識別一個目標(biāo)類中@Classifier注解的方法般眉,把它作為轉(zhuǎn)換的實現(xiàn)類了赵,在需要轉(zhuǎn)換時候調(diào)用。 - 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,它們就都會被捕獲重試襟沮。 - 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: 穿過、橫貫
- PatternMatcher和PatternMatchingClassifier<T> :
能夠把符合樣式的字符串轉(zhuǎn)換為T對象的轉(zhuǎn)換器巫玻。
其核心方法為imatch()丛忆,對?和*進(jìn)行了處理判斷,判斷輸入的str是否符合某種樣式pattern仍秤。 - BackToBackPatternClassifier<C, T> 類:
背對背映射組合熄诡,先吧C對象轉(zhuǎn)換為string,然后再把string轉(zhuǎn)換為T對象。
retry頂級接口
retry頂級接口定義了核心的概念徒扶,其相互關(guān)系如下:
具體含義:請移步spring-retry(1.概念和基本用法)粮彤,這里簡要分析一些接口方法。
- RetryContext接口:
從圖上可以看到姜骡,重試上下文處于核心位置,作為核心數(shù)據(jù)接口圈澈,儲存了重試所需要的各類信息惫周。
RetryContext getParent();
從獲取父上下文方法可知递递,它是一個鏈?zhǔn)浇Y(jié)構(gòu)疙剑。
- 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)行判斷分析的舟扎。
- RetryOperations接口:
各種花式execute(),根據(jù)可配置的重試行為分飞,進(jìn)行方法的執(zhí)行,其具體的實現(xiàn)就是核心類RetryTemplate - RetryListener接口:
作為重試動作的監(jiān)聽器睹限,給spring-retry加點料譬猫,用在統(tǒng)計機(jī)制上。監(jiān)聽3類動作:open()在開啟操作之前羡疗,close()在關(guān)閉操作之后染服,onError()在出現(xiàn)錯誤時。 - RetryStatistics接口:
記錄重試統(tǒng)計信息的接口叨恨。登記完成數(shù)柳刮、開始數(shù)、錯誤數(shù)、中止數(shù)、恢復(fù)數(shù)和措。 - RetryException及ExhaustedRetryException背桐,TerminatedRetryException異常
定義了retry項目內(nèi)部可能拋出的異常,RetryException是基類搅荞。
Exhausted:精疲力竭的
Terminated:終止的
retry.backoff 包
該包定義了當(dāng)出現(xiàn)異常,而又會重試的情況下的補(bǔ)償機(jī)制(通常就是延時)。
- BackOffPolicy接口:
該包的核心接口菇怀,包含兩個方法凭舶,意識生成一個當(dāng)前補(bǔ)償上下文環(huán)境,二是進(jìn)行補(bǔ)償動作爱沟。
//根據(jù)重試上下文生成一個補(bǔ)償上下文
BackOffContext start(RetryContext context);
//根據(jù)補(bǔ)償上下文執(zhí)行延遲操作帅霜,可能拋出中斷異常
void backOff(BackOffContext backOffContext) throws BackOffInterruptedException;
- Sleeper接口與ThreadWaitSleeper類:
真正的補(bǔ)償動作具體執(zhí)行器, ThreadWaitSleeper就是調(diào)用了Thread.sleep()方法進(jìn)行延遲呼伸。 - StatelessBackOffPolicy抽象類:
其start方法返回null义屏,也就是沒有重試上下文,執(zhí)行backOff時候調(diào)用的是無參數(shù)的doBackOff()蜂大。換句話說闽铐,代表具體補(bǔ)償動作是固定的,并不依賴上下文環(huán)境奶浦。 - NoBackOffPolicy類:
最簡單的默認(rèn)策略兄墅,具體延遲為空操作,也就是不補(bǔ)償澳叉,不延遲隙咸。 - SleepingBackOffPolicy接口:
有一個withSleeper()方法,傳入一個Sleeper成洗。 - UniformRandomBackOffPolicy類:
標(biāo)準(zhǔn)的隨機(jī)延遲策略五督,給定最小值,最大值(默認(rèn)為500L瓶殃,1500L)充包,會在這個區(qū)間里面隨機(jī)進(jìn)行補(bǔ)償延遲。
7 FixedBackOffPolicy類:
標(biāo)準(zhǔn)的固定延遲策略遥椿,每次延遲固定時間(默認(rèn)1000L) - 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)钢悲。
- 擴(kuò)展AttributeAccessorSupport:內(nèi)部有個linkedHashMap存儲標(biāo)準(zhǔn)屬性外的其他屬性
- 有parent屬性,在構(gòu)造時候傳入其父上下文舔株,這樣就維護(hù)了一個鏈表信息莺琳,方便后續(xù)查找。
- count和lastException是記錄型屬性督笆,登記這個上下文的狀態(tài)芦昔。