Spring Boot小組件 - FailureAnalyzer


前言

一個Spring Boot 應用偶爾會因為某些原因啟動失敗,此時Spring Boot會友好地輸出類似於這樣一段文字,告訴你發生了什么,甚至應該采取什么行動:

***************************

APPLICATION FAILED TO START

***************************

Description:

Parameter 0 of constructor in com.example.B required a bean of type 'com.example.A' that could not be found.

Action:

Consider defining a bean of type 'com.example.A' in your configuration.

這是怎么做到的呢?或許第一想法是SpringBoot會在出現問題的地方構造這樣完整的異常和輸出。實際上並非如此,Spring Boot提供了統一的接口進行問題的分析和診斷,這就是org.springframework.boot.diagnostics.FailureAnalyzer 接口。

本文所使用的源碼版本為 2.2.2.RELEASE,如有出入請檢查版本是否不一致。

從哪開始

已知Spring Boot項目是通過調用SpringApplication#run(java.lang.String...)啟動的。我們會發現當啟動過程拋出異常時,是這樣處理的:

catch (Throwable ex) {
	handleRunFailure(context, ex, exceptionReporters, listeners);
	// ...
}

觀察一下找到方法參數中exceptionReporters就是用來報告處理異常的,回過頭來尋找其定義,發現其通過SpringFactoriesLoader#loadFactoryNames加載classpath下META-INF中spring.factories里定義的SpringBootExceptionReporter實現類。

一般只有FailureAnalyzers這一個實現類,里面的處理也很簡潔:通過SpringFactoriesLoader加載到所有定義的FailureAnalyzer實現,然后稍微prepare一下。分析異常時遍歷所有的FailureAnalyzer看誰能分析到問題就好了。分析完呢還要報告分析結果,又是加載了FailureAnalysisReporter所有實現類,然后一個一個報告。通常也只有一個,就是我們在“前言”中看到輸出日志的LoggingFailureAnalysisReporter

SpringFactoriesLoader 類似於Java原生的SPI,可以通過編寫配置文件為某個接口尋找服務實現。

做一個自己的

如果做一個自己的組件,就可能會遇上需要處理異常並向使用者提供建議的情況。

我們定義一個異常

public class WannaStopException extends RuntimeException {
}

我們定義一個Bean在某(全)種(部)情況下會拋出異常

@Service
public class A {
    public A() {
        throw new WannaStopException();
    }
}

我們定義一個FailureAnalyzer專門處理這個WannaStopException

public class StopFailureAnalyzer extends AbstractFailureAnalyzer<WannaStopException> {
    @Override
    protected FailureAnalysis analyze(Throwable rootFailure, WannaStopException cause) {
        for (StackTraceElement stackTraceElement : cause.getStackTrace()) {
            if (stackTraceElement.getClassName().equals("com.example.A")) {
                return new FailureAnalysis("A想停止", "別要A了", cause); } } return null; } } 

AbstractFailureAnalyzer 幫助我們找到特定異常

接下來我們還要把StopFailureAnalyzer放進spring.factories中,在resources/META-INF/spring.factories(自己建)里添加

org.springframework.boot.diagnostics.FailureAnalyzer=\ com.example.flowable.StopFailureAnalyzer 

啟動這個應用,就能看到如下輸出

***************************

APPLICATION FAILED TO START

***************************

Description:

A想停止

Action:

別要A了

另外也注意到FailureAnalysisReporter可以用來向開發進行報警,或者進行一些自動修復操作(如自動回滾)等。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM