springboot
在專案啟動時如果遇到異常並不能友好的列印出具體的堆疊錯誤資訊
,我們只能檢視到簡單的錯誤訊息,以致於並不能及時解決發生的問題,針對這個問題springboot
提供了故障分析儀的概念(failure-analyzer),內部根據不同型別的異常提供了一些實現,我們如果想自定義該怎麼去做?
springboot提供了啟動異常分析介面failureanalyzer
,該介面位於org.springframework.boot.diagnostics
package內。內部僅提供乙個分析的方法,原始碼如下所示:
@functionalinte***ce
public inte***ce failureanalyzer , or if no analysis
* was possible.
* @param failure the failure
* @return the analysis or
*/failureanalysis analyze(throwable failure);
}
該介面會把遇到的異常物件例項throwable failure
交付給實現類,實現類進行自定義處理。
abstractfailureanalyzer
是failureanalyzer
的基礎實現抽象類,實現了failureanalyzer
定義的analyze(throwable failure)
方法,並提供了乙個指定異常型別的抽象方法analyze(throwable rootfailure, t cause)
,原始碼如下所示:
public abstract class abstractfailureanalyzerimplements failureanalyzer
return null;
}/**
* returns an analysis of the given , or if no
* analysis was possible.
* @param rootfailure the root failure passed to the analyzer
* @param cause the actual found cause
* @return the analysis or
*/protected abstract failureanalysis analyze(throwable rootfailure, t cause);
/*** return the cause type being handled by the analyzer. by default the class generic
* is used.
* @return the cause type
*/@suppresswarnings("unchecked")
protected class extends t> getcausetype()
@suppresswarnings("unchecked")
protected final e findcause(throwable failure, classtype)
failure = failure.getcause();
}return null;}}
通過abstractfailureanalyzer
原始碼我們可以看到,它在實現於failureanalyzer
的介面方法內進行了特殊處理,根據getcausetype()
方法獲取當前類定義的第乙個泛型型別,也就是我們需要分析的指定異常型別
。
獲取泛型異常型別後根據方法findcause
判斷throwable
是否與泛型異常型別匹配,如果匹配直接返回給springboot
進行註冊處理。
springboot
內部通過實現abstractfailureanalyzer
抽象類定義了一系列的針對性異常型別的啟動分析,如下圖所示:
springboot
內部提供的啟動異常分析都是指定具體的異常型別實現的,最常見的乙個錯誤就是埠號被占用(portinuseexception
),雖然springboot
內部提供乙個這個異常的啟動分析,我們也是可以進行替換這一異常分析的,我們只需要建立portinuseexception
異常的abstractfailureanalyzer
,並且實現類註冊給springboot
即可,實現自定義如下所示:
/**
* 埠號被占用異常啟動分析
* * @author 恆宇少年
*/public class portinusefailureanalyzer extends abstractfailureanalyzer
}
在上面我們只是編寫了指定異常啟動分析,我們接下來需要讓它生效,這個生效方式比較特殊,類似於自定義springboot starter autoconfiguration
的形式,我們需要在meta-inf/spring.factories
檔案內進行定義,如下所示:
org.springframework.boot.diagnostics.failureanalyzer=\
org.minbox.chapter.springboot.failure.analyzer.portinusefailureanalyzer
那我們為什麼需要使用這種方式定義呢?專案啟動遇到的異常順序不能確定,很可能在spring ioc
並未執行初始化之前就出現了異常,我們不能通過@component
註解的形式使其生效,所以springboot
提供了通過spring.factories
配置檔案的方式定義。
自定義的執行異常一般都是繼承自runtimeexception
,如果我們定義乙個runtimeexception
的異常啟動分析例項會是什麼效果呢?
/**
* 專案啟動執行時異常統一啟動分析
* * @author 恆宇少年
*/public class projectbootunifiedfailureanalyzer extends abstractfailureanalyzer
}
將該類也一併註冊到spring.factories
檔案內,如下所示:
org.springframework.boot.diagnostics.failureanalyzer=\
org.minbox.chapter.springboot.failure.analyzer.portinusefailureanalyzer,\
org.minbox.chapter.springboot.failure.analyzer.projectbootunifiedfailureanalyzer
執行專案並測試埠號被占用異常
我們會發現,並沒有執行projectbootunifiedfailureanalyzer
內的analyze
方法,而是繼續執行了portinusefailureanalyzer
類內的方法。
那我們將portinusefailureanalyzer
這個啟動分析從spring.factories
檔案內暫時刪除掉
,再來執行專案我們會發現這時卻是會執行projectbootunifiedfailureanalyzer
類內分析方法。
根據本章我們了解了springboot
提供的啟動異常分析介面以及基本抽象實現類的運作原理,而且啟動異常分析存在分析泛型異常類的上下級繼承關係,異常子類的啟動分析會覆蓋掉異常父類的啟動分析,如果你想包含全部異常的啟動分析可以嘗試使用exception
作為abstractfailureanalyzer
的泛型引數。
SpringBoot詳細列印啟動時異常堆疊資訊
springboot在專案啟動時如果遇到異常並不能友好的列印出具體的堆疊錯誤資訊,我們只能檢視到簡單的錯誤訊息,以致於並不能及時解決發生的問題,針對這個問題springboot提供了故障分析儀的概念 failure analyzer 內部根據不同型別的異常提供了一些實現,我們如果想自定義該怎麼去做?...
SpringBoot中Mybatis列印sql日誌
springboot mybatis 控制台列印sql語句 方式一 logging level 配置slq列印日誌 方式二 mybatis plus configuration log impl org.apache.ibatis.logging.stdout.stdoutimpl 上面二選一就可以...
spring boot 配置不占用埠方式啟動
在配置檔案中加入 不過這裡有個點需要注意,如果配置成不占用埠的方式啟動,若main方法執行完後,沒其他的deamon執行緒在跑,應用就會自動關閉了,有些新同學最容易放這種錯誤,並且還不清楚錯誤在哪 在使用阻塞執行緒時,這裡也有個坑,有人使用system.in.read 進行阻塞,這種寫法在windo...