SpringBoot FailureAnalyzer實例使用教程
SpringBoot自定義FailureAnalyzer
今天在學(xué)習(xí)Spring Boot 源碼的過程中,在spring.factories 文件中無意中發(fā)現(xiàn)了FailureAnalyzer 這個接口。由于之前沒有接觸過,今天來學(xué)習(xí)一下 FailureAnalyzer 接口的作用。
在學(xué)習(xí)FailureAnalyzer之前, 我們先看以下截圖

相信Spring的開發(fā)者,或多或少的遇到過以上的錯誤。由于端口占用阻止了應(yīng)用程序啟動,這跟今天的主角有關(guān)系。Spring Boot 應(yīng)用程序啟動時,F(xiàn)ailureAnalyzer接口攔截啟動過程中發(fā)生的異常,并終止啟動。
FailureAnalyzer
核心接口定義
package org.springframework.boot.diagnostics;
/**
* 該接口用戶分析異常堆棧信息,將其轉(zhuǎn)換為用戶可讀的對象信息,通常情況下,對象包含錯誤描述和建議.
* @since 1.4.0
*/
@FunctionalInterface
public interface FailureAnalyzer {
/**
* 返回異常錯誤的分析對象,或null
* @param failure the failure
* @return the analysis or {@code null}
*/
FailureAnalysis analyze(Throwable failure);
}
FailureAnalyzer 定義為函數(shù)式接口,因此可以使用Lambda表達式實現(xiàn)接口,簡化代碼開發(fā)。從定義上可以看出接收 Throwable 類型的參數(shù),返回失敗分析對象 - FailureAnalysis
FailureAnalysis對象
package org.springframework.boot.diagnostics;
/**
* The result of analyzing a failure.
*
* @author Andy Wilkinson
* @since 1.4.0
*/
public class FailureAnalysis {
// 問題描述
private final String description;
// 動作(解決問題的方法)
private final String action;
// 問題原因
private final Throwable cause;
public FailureAnalysis(String description, String action, Throwable cause) {
this.description = description;
this.action = action;
this.cause = cause;
}
// get 方法...
}
PortInUseFailureAnalyzer
以文章開頭的報錯信息為例,PortInUseFailureAnalyzer 繼承AbstractFailureAnalyzer抽象類,最終實現(xiàn)了端口占用報錯信息的分析。
package org.springframework.boot.diagnostics.analyzer;
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
import org.springframework.boot.diagnostics.FailureAnalysis;
import org.springframework.boot.web.server.PortInUseException;
class PortInUseFailureAnalyzer extends AbstractFailureAnalyzer<PortInUseException> {
@Override
protected FailureAnalysis analyze(Throwable rootFailure, PortInUseException cause) {
return new FailureAnalysis("Web server failed to start. Port " + cause.getPort() + " was already in use.",
"Identify and stop the process that's listening on port " + cause.getPort() + " or configure this "
+ "application to listen on another port.",
cause);
}
}
AbstractFailureAnalyzer
public abstract class AbstractFailureAnalyzer<T extends Throwable> implements FailureAnalyzer {
@Override
public FailureAnalysis analyze(Throwable failure) {
T cause = findCause(failure, getCauseType());
return (cause != null) ? analyze(failure, cause) : null;
}
/**
* 重新定義鉤子方法,將參數(shù)與泛型對象關(guān)聯(lián),具象化了每一個子類需要實現(xiàn)的功能
*/
protected abstract FailureAnalysis analyze(Throwable rootFailure, T cause);
@SuppressWarnings("unchecked")
protected Class<? extends T> getCauseType() {
return (Class<? extends T>) ResolvableType.forClass(AbstractFailureAnalyzer.class, getClass()).resolveGeneric();
}
@SuppressWarnings("unchecked")
protected final <E extends Throwable> E findCause(Throwable failure, Class<E> type) {
while (failure != null) {
if (type.isInstance(failure)) {
return (E) failure;
}
failure = failure.getCause();
}
return null;
}
}
FailureAnalyzer接口的核心抽象類,并重新擴展了FailureAnalyzer接口定義的功能。該抽象類實現(xiàn)了Exception對象與失敗分析實現(xiàn)類一一對應(yīng)的功能。如
//PortInUseFailureAnalyzer 負責(zé)解析 PortInUseException 異常
class PortInUseFailureAnalyzer extends AbstractFailureAnalyzer<PortInUseException>{
...
}
FailureAnalyzer-自定義
上面提到過具體的失敗分析類,是跟每一種Exception類對應(yīng)的,那么我們從定義異常類開始
定義異常類
package com.andy.spring.boot.docker.exception;
public class CustomApplicationException extends RuntimeException {
public CustomApplicationException(String msg){
super(msg);
}
}
異常類定義完畢后,需要定義解析該異常的失敗分析類
實現(xiàn)FailureAnalyzer
package com.andy.spring.boot.docker.analyzer;
import com.andy.spring.boot.docker.exception.CustomApplicationException;
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
import org.springframework.boot.diagnostics.FailureAnalysis;
public class CustomApplicationFailureAnalyzer extends AbstractFailureAnalyzer<CustomApplicationException> {
@Override
protected FailureAnalysis analyze(Throwable rootFailure, CustomApplicationException cause) {
return new FailureAnalysis("Yeah, 自定義失敗分析器出現(xiàn)了...!",
"Ummm... 啥都不做,刪庫跑路",
cause);
}
}
接下來,需要Spring
添加spring.factories
接下來,需要Spring Boot 框架識別失敗分析。SPI機制出場,在resources/META-INF目錄下創(chuàng)建spring.factories文件,內(nèi)容如下
org.springframework.boot.diagnostics.FailureAnalyzer=com.andy.spring.boot.docker.analyzer.CustomApplicationFailureAnalyzer
驗證測試
測試代碼
到目前為止,萬事具備,只欠東風(fēng)。我們需要在應(yīng)用啟動時,拋出自定義異常即可
package com.andy.spring.boot.docker.service;
import com.andy.spring.boot.docker.exception.CustomApplicationException;
import org.springframework.stereotype.Component;
@Component
public class CacheService {
public CacheService() {
throw new CustomApplicationException("bean 初始化異常");
}
}
驗證結(jié)果
重新啟動應(yīng)用程序,出現(xiàn)以下錯誤

到此這篇關(guān)于SpringBoot FailureAnalyzer實例使用教程的文章就介紹到這了,更多相關(guān)SpringBoot FailureAnalyzer內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot集成Redis向量數(shù)據(jù)庫實現(xiàn)相似性搜索功能
Redis?是一個開源(BSD?許可)的內(nèi)存數(shù)據(jù)結(jié)構(gòu)存儲,用作數(shù)據(jù)庫、緩存、消息代理和流式處理引擎,向量檢索的核心原理是通過將文本或數(shù)據(jù)表示為高維向量,并在查詢時根據(jù)向量的相似度進行搜索,本文給大家介紹了SpringBoot集成Redis向量數(shù)據(jù)庫實現(xiàn)相似性搜索功能2024-09-09
SpringBoot 集成MQTT實現(xiàn)消息訂閱的詳細代碼
本文介紹了如何在SpringBoot中集成MQTT并實現(xiàn)消息訂閱,主要步驟包括添加依賴、配置文件設(shè)置、啟動類注解、MQTT配置類、消息處理器配置、主題緩存、動態(tài)數(shù)據(jù)庫主題配置以及消息處理服務(wù),感興趣的朋友跟隨小編一起看看吧2024-11-11
IDEA2020 1.1中Plugins加載不出來的問題及解決方法
這篇文章主要介紹了IDEA2020 1.1中Plugins加載不出來的問題,本文還給大家提到了IDEA 2020.1.1 找不到程序包和符號的問題,感興趣的朋友跟隨小編一起看看吧2020-06-06
TOMCAT內(nèi)存溢出及大小調(diào)整的實現(xiàn)方法
下面小編就為大家?guī)硪黄猅OMCAT內(nèi)存溢出及大小調(diào)整的實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05

