最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot的FailureAnalyzer機(jī)制及如何解救應(yīng)用啟動(dòng)危機(jī)

 更新時(shí)間:2025年01月24日 10:09:00   作者:張彥峰ZYF  
本文探討了FailureAnalyzer工具,它不僅能幫助我們快速識(shí)別和處理代碼中的錯(cuò)誤,還能極大地提升我們的開發(fā)效率,通過詳細(xì)的實(shí)例分析,我們了解了FailureAnalyzer如何通過自定義邏輯應(yīng)對(duì)不同類型的異常,讓程序員能夠更好地定位問題并迅速找到解決方案,感興趣的朋友一起看看吧

在程序員的世界里,錯(cuò)誤就像鄰居家的狗,總是無時(shí)無刻不在你的代碼中“汪汪”作響,仿佛在說:“嘿,注意我,我又來了!”當(dāng)你優(yōu)雅地寫完一段代碼,按下回車鍵,心里滿是期待時(shí),突然跳出來一個(gè)神秘的異常,這感覺就像是開門見到一只大黑狗——又驚又怕。

但是,別擔(dān)心,今天我們要介紹的“FailureAnalyzer”就像一位經(jīng)驗(yàn)豐富的獸醫(yī),專門為你的代碼診斷問題,幫你把那些不請(qǐng)自來的錯(cuò)誤處理得服服帖帖!它不僅能識(shí)別出問題所在,還能給你提供相應(yīng)的解決方案,讓你的代碼重新煥發(fā)生機(jī),宛如一只朝氣蓬勃的小狗,搖著尾巴跑向美好的明天。

在這篇文章中,我們將一起探索FailureAnalyzer的奧秘,學(xué)習(xí)如何自定義它以應(yīng)對(duì)那些棘手的錯(cuò)誤。準(zhǔn)備好了嗎?讓我們帶上“程序員的護(hù)目鏡”,一起踏上這場充滿挑戰(zhàn)和樂趣的冒險(xiǎn)之旅吧!

一、走進(jìn)FailureAnalyzer

想象一下,你正在開發(fā)一個(gè)基于Spring Boot的網(wǎng)絡(luò)應(yīng)用程序,你已經(jīng)編寫了一大堆代碼,做了各種配置,終于迫不及待地想要啟動(dòng)你的應(yīng)用程序,看看它是不是如你所愿地運(yùn)行。

你興奮地運(yùn)行了啟動(dòng)命令,但突然間,控制臺(tái)上出現(xiàn)了一堆紅色的錯(cuò)誤信息。如下:

可以立刻看到這個(gè)報(bào)錯(cuò)來自于LoggingFailureAnalysisReporter,其內(nèi)部其實(shí)就是Spring Boot中被譽(yù)為故障排查神器的工具FailureAnalyzer。你決定讓它出馬,看看能否解決你的問題。

你應(yīng)該感到非常驚訝和興奮,因?yàn)?code>FailureAnalyzer不僅僅找出了問題,還給出了解決方案:按照建議修復(fù)了配置,再次啟動(dòng)應(yīng)用程序,這一次一切都運(yùn)行得非常順利。

通過這個(gè)簡單的場景,你立刻感受到了FailureAnalyzer的價(jià)值和魔力。它就像是你的應(yīng)用程序啟動(dòng)的保險(xiǎn),讓你在遇到問題時(shí)能夠迅速找出解決方案,讓你的開發(fā)過程更加流暢和高效。

二、在Spring Boot中如何生效

在Spring Boot的spring.factories文件(位于META-INF目錄下)中已經(jīng)包含了一些FailureAnalyzer的配置,FailureAnalyzer實(shí)現(xiàn)類通常在spring.factories文件中被聲明,以便在應(yīng)用程序啟動(dòng)時(shí)被Spring Boot自動(dòng)發(fā)現(xiàn)并注冊(cè)。

org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.autoconfigure.jdbc.DataSourceFailedAnalyzer,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQConnectFailureAnalyzer,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisJmsConnectionFailureAnalyzer,\
org.springframework.boot.autoconfigure.jms.hornetq.HornetQConnectFailureAnalyzer,\
org.springframework.boot.autoconfigure.jms.hornetq.HornetQDependencyExceptionAnalyzer,\
org.springframework.boot.autoconfigure.solr.SolrExceptionAnalyzer,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBeanNotAvailableAnalyzer,\
org.springframework.boot.cloud.CloudPlatformConnectorsFailureAnalyzer,\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessorFailureAnalyzer,\
org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessorChecker,\
org.springframework.boot.devtools.autoconfigure.DevToolsMissingFilterFailureAnalyzer,\
org.springframework.boot.devtools.autoconfigure.LocalDevToolsAutoConfiguration$LocalDevToolsFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanDefinitionOverrideAnalyzer,\
org.springframework.boot.diagnostics.analyzer.IllegalComponentScanFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidEmbeddedServletContainerConfigurationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidTemplateAvailabilityProviderAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NonCompatibleConfigurationClassFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.SingleConstructorInjectionAnalyzer

當(dāng)應(yīng)用程序啟動(dòng)失敗時(shí),Spring Boot會(huì)自動(dòng)觸發(fā)這個(gè)機(jī)制,嘗試識(shí)別和處理啟動(dòng)失敗的原因,并提供有用的診斷信息和解決方案。

三、為什么可能需要自定義FailureAnalyzer

當(dāng)然,如果有需要的話,我們可以自定義FailureAnalyzer來更靈活地處理應(yīng)用程序啟動(dòng)失敗的情況,提供更精準(zhǔn)的故障診斷和解決方案等,特別是針對(duì)做基礎(chǔ)架構(gòu)的同學(xué)。

理由說明
特定錯(cuò)誤情況處理

默認(rèn)的FailureAnalyzer無法準(zhǔn)確識(shí)別或處理特定的錯(cuò)誤情況。通過自定義可以針對(duì)這些特定的錯(cuò)誤情況編寫定制化的診斷邏輯,提供更精準(zhǔn)的故障診斷和解決方案。

額外的診斷信息

默認(rèn)的FailureAnalyzer只提供基本的診斷信息,但在某些情況下,可能需要更多的詳細(xì)信息來準(zhǔn)確診斷問題。通過自定義可添加額外的診斷邏輯,收集更多有用的信息來更好地理解問題。

集成外部系統(tǒng)應(yīng)用程序與外部系統(tǒng)集成,而啟動(dòng)失敗可能是由于與這些外部系統(tǒng)的交互出現(xiàn)問題所致。通過自定義可以集成額外的邏輯,例如調(diào)用外部API或檢查外部系統(tǒng)的狀態(tài),以診斷和解決與外部系統(tǒng)相關(guān)的問題。
定制化的解決方案某些錯(cuò)誤情況需要特定的解決方案,通過自定義可以根據(jù)應(yīng)用程序的特定需求或約束,提供定制化的解決方案,以更好地滿足應(yīng)用程序的需求。

四、實(shí)現(xiàn)自定義基本步驟

(一)完整步驟要求

要實(shí)現(xiàn)自定義的FailureAnalyzer,我們需要完成以下步驟:

  • 自定義異常,并創(chuàng)建檢查要求規(guī)定。
  • 創(chuàng)建一個(gè)類并實(shí)現(xiàn)AbstractFailureAnalyzer接口,重寫analyze()方法,用于分析異常并返回FailureAnalysis對(duì)象。
  • 將自定義的FailureAnalyzer類注冊(cè)到Spring Boot應(yīng)用程序中。

注意在 Spring Boot 應(yīng)用程序中,自定義的多個(gè)失敗分析器在實(shí)現(xiàn)上沒有固定的先后次序。當(dāng)應(yīng)用程序啟動(dòng)時(shí),Spring Boot 會(huì)自動(dòng)掃描并注冊(cè)所有的失敗分析器,然后按照它們的類名順序進(jìn)行調(diào)用。這意味著,無論你如何組織和編寫你的失敗分析器類,它們都將在應(yīng)用程序啟動(dòng)時(shí)同時(shí)注冊(cè),并且沒有先后次序。

(二)注冊(cè)方式說明

要讓自定義的FailureAnalyzer生效注冊(cè)到Spring Boot應(yīng)用程序中,一般有兩種方法:

通過Spring Boot的spring.factories文件(建議方式)

  • src/main/resources目錄下創(chuàng)建一個(gè)名為META-INF/spring.factories的文件(如果已存在則跳過此步驟)。
  • spring.factories文件中添加用于實(shí)現(xiàn)的自定義FailureAnalyzer類,和上文中展示的spring.factories文件中的格式一樣。

在啟動(dòng)類中手動(dòng)注冊(cè)(本人不建議)

在Spring Boot應(yīng)用程序的啟動(dòng)類(@SpringBootApplication)中手動(dòng)注冊(cè)FailureAnalyzer

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(ZYFApplication.class);
        application.addListeners(new ConfigFileFailureAnalyzer());
        application.run(args);
    }

后續(xù)列舉一些案例,但是情況請(qǐng)依據(jù)實(shí)際項(xiàng)目需求來定。我一般是以上面建議方式進(jìn)行寫的注冊(cè)。

五、實(shí)現(xiàn)自定義舉例

假設(shè)我們的應(yīng)用程序在啟動(dòng)時(shí)需要加載某些特定的配置文件,但如果對(duì)應(yīng)配置文件不存在將導(dǎo)致應(yīng)用程序啟動(dòng)失敗。默認(rèn)的FailureAnalyzer可能無法準(zhǔn)確地識(shí)別或處理這種特定情況,因此我們可以自定義一個(gè)FailureAnalyzer來處理這種特定的錯(cuò)誤情況。

首先定義必要文件未找到異常如下:

package org.zyf.javabasic.spring.failureanalyzer.exception;
/**
 * @program: zyfboot-javabasic
 * @description: ConfigFileNotFoundException
 * @author: zhangyanfeng
 * @create: 2024-05-02 17:25
 **/
public class ConfigFileNotFoundException extends RuntimeException {
    private final String fileNames;
    public ConfigFileNotFoundException(String fileNames) {
        super("Configuration file '" + fileNames + "' not found");
        this.fileNames = fileNames;
    }
    public String getFileNames() {
        return fileNames;
    }
}

接著創(chuàng)建檢查類對(duì)我們系統(tǒng)要求的必要文件作出基本的檢查并返回要求文件異?;拘畔ⅲ?/p>

package org.zyf.javabasic.spring.failureanalyzer.checker;
import com.google.common.collect.Lists;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import org.zyf.javabasic.spring.failureanalyzer.exception.ConfigFileNotFoundException;
import javax.annotation.PostConstruct;
import java.util.List;
/**
 * @program: zyfboot-javabasic
 * @description: 系統(tǒng)必要配置文件檢查
 * @author: zhangyanfeng
 * @create: 2024-05-02 18:14
 **/
@Component
public class ConfigFileNotFoundChecker {
    private final ResourceLoader resourceLoader;
    public ConfigFileNotFoundChecker(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
    public boolean exists(String fileName) {
        Resource resource = resourceLoader.getResource("classpath:" + fileName);
        return resource.exists();
    }
    @PostConstruct
    public void checkConfigFiles() throws ConfigFileNotFoundException {
        // 要檢查的文件列表
        List<String> filesToCheck = Lists.newArrayList();
        filesToCheck.add("application.yml");
        filesToCheck.add("zyf_application_context.xml");
        filesToCheck.add("report-config.xml");
        filesToCheck.add("urlzyf.properties");
        // 存儲(chǔ)不存在的文件名
        List<String> notFoundFiles = Lists.newArrayList();
        // 檢查每個(gè)文件是否存在
        for (String fileName : filesToCheck) {
            if (!exists(fileName)) {
                notFoundFiles.add(fileName);
            }
        }
        // 如果存在未找到的文件,則拋出異常
        if (!notFoundFiles.isEmpty()) {
            throw new ConfigFileNotFoundException(notFoundFiles.toString());
        }
    }
}

接著創(chuàng)建并實(shí)現(xiàn)AbstractFailureAnalyzer,重寫analyze()方法如下:

package org.zyf.javabasic.spring.failureanalyzer.analyzer;
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
import org.springframework.boot.diagnostics.FailureAnalysis;
import org.zyf.javabasic.spring.failureanalyzer.exception.ConfigFileNotFoundException;
import org.zyf.javabasic.spring.failureanalyzer.exception.RequiredPropertyException;
/**
 * @program: zyfboot-javabasic
 * @description: 檢查必要文件是否存在異常
 * @author: zhangyanfeng
 * @create: 2024-05-02 18:26
 **/
public class ZYFConfigFileFailureAnalyzer extends AbstractFailureAnalyzer<ConfigFileNotFoundException> {
    @Override
    protected FailureAnalysis analyze(Throwable rootFailure, ConfigFileNotFoundException cause) {
        String description = description(cause);
        String action = action(cause);
        return new FailureAnalysis(description, action, cause);
    }
    private String description(ConfigFileNotFoundException ex) {
        return String.format("Failed to load configuration file '%s'.", ex.getFileNames());
    }
    private String action(ConfigFileNotFoundException ex) {
        return String.format("Check if the configuration file:'%s' exists.", ex.getFileNames());
    }
}

spring.factories中增加本次新增驗(yàn)證:

org.springframework.boot.diagnostics.FailureAnalyzer=\
org.zyf.javabasic.spring.failureanalyzer.analyzer.ZYFConfigFileFailureAnalyzer

現(xiàn)在其中本地未創(chuàng)建ourlzyf.properties文件,故程序啟動(dòng)報(bào)錯(cuò)如下:

符合我們的預(yù)期。

接著如果要求針對(duì)報(bào)告配置文件 report-config.xml 中必須包含數(shù)據(jù)庫連接信息和報(bào)告生成器的情況,并要求有更加詳細(xì)和嚴(yán)格的配置文件格式驗(yàn)證,接著我們繼續(xù)定義一個(gè)異常類且需要指明異常情況。

先定義一個(gè)這種類型返回的基本配置錯(cuò)誤信息如下:

package org.zyf.javabasic.spring.failureanalyzer.model;
/**
 * @program: zyfboot-javabasic
 * @description: 表示不同的錯(cuò)誤類型,例如缺少必要屬性、屬性值格式錯(cuò)誤等
 * @author: zhangyanfeng
 * @create: 2024-05-02 19:57
 **/
public class ConfigFileFormatErrorInfo {
    private final boolean fileNotFound;
    private final ErrorType errorType;
    private final String fileName;
    public ConfigFileFormatErrorInfo(boolean fileNotFound, ErrorType errorType, String fileName) {
        this.fileNotFound = fileNotFound;
        this.errorType = errorType;
        this.fileName = fileName;
    }
    public boolean isFileNotFound() {
        return fileNotFound;
    }
    public ErrorType getErrorType() {
        return errorType;
    }
    public String getFileName() {
        return fileName;
    }
    public DescriptionAndAction getDescriptionAndAction() {
        String description;
        String action;
        if (fileNotFound) {
            description = "Configuration file '" + fileName + "' not found";
            action = "Check if the configuration file exists.";
        } else {
            switch (errorType) {
                case MISSING_PROPERTY:
                    description = "Missing required property in configuration file '" + fileName + "'";
                    action = "Ensure all required properties are provided in the configuration file.";
                    break;
                case INVALID_VALUE:
                    description = "Invalid value for property in configuration file '" + fileName + "'";
                    action = "Correct the value of the property in the configuration file.";
                    break;
                case OTHER:
                default:
                    description = "Other configuration file format error in file '" + fileName + "'";
                    action = "Review the configuration file for formatting issues.";
                    break;
            }
        }
        return new DescriptionAndAction(description, action);
    }
    public enum ErrorType {
        MISSING_PROPERTY,
        INVALID_VALUE,
        OTHER
    }
}
package org.zyf.javabasic.spring.failureanalyzer.model;
/**
 * @program: zyfboot-javabasic
 * @description: DescriptionAndAction
 * @author: zhangyanfeng
 * @create: 2024-05-02 20:19
 **/
public class DescriptionAndAction {
    private final String description;
    private final String action;
    public DescriptionAndAction(String description, String action) {
        this.description = description;
        this.action = action;
    }
    public String getDescription() {
        return description;
    }
    public String getAction() {
        return action;
    }
}

然后定義基本的異常信息如下:

package org.zyf.javabasic.spring.failureanalyzer.exception;
import com.alibaba.fastjson.JSON;
import org.zyf.javabasic.spring.failureanalyzer.model.ConfigFileFormatErrorInfo;
/**
 * @program: zyfboot-javabasic
 * @description: 配置文件格式問題異常
 * @author: zhangyanfeng
 * @create: 2024-05-02 19:23
 **/
public class ConfigFileFormatException extends RuntimeException {
    private final ConfigFileFormatErrorInfo errorInfo;
    public ConfigFileFormatException(ConfigFileFormatErrorInfo errorInfo) {
        super("Configuration file format error: " + JSON.toJSONString(errorInfo));
        this.errorInfo = errorInfo;
    }
    public ConfigFileFormatErrorInfo getErrorInfo() {
        return errorInfo;
    }
}

檢查指定的配置文件(report-config.xml)是否符合預(yù)期的格式要求:

  • 必須包含一個(gè)名為 "dataSource" 的 Bean 定義,用于配置數(shù)據(jù)庫連接信息。
  • "dataSource" Bean 中必須包含以下屬性:driverClassName:數(shù)據(jù)庫驅(qū)動(dòng)類名;url:數(shù)據(jù)庫連接 URL;username:數(shù)據(jù)庫用戶名;password:數(shù)據(jù)庫密碼。
  • password 屬性必須已加密,即以特定字符串開頭。
  • 必須包含一個(gè)名為 "reportGenerator" 的 Bean 定義,用于配置報(bào)告生成器。
  • "reportGenerator" Bean 中必須包含一個(gè)名為 dataSource 的屬性引用,指向之前定義的 "dataSource" Bean。

如果配置文件不符合上述要求之一,就會(huì)拋出相應(yīng)的異常,指示配置文件格式錯(cuò)誤。具體對(duì)應(yīng)的檢查實(shí)現(xiàn)如下:

package org.zyf.javabasic.spring.failureanalyzer.checker;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.zyf.javabasic.spring.failureanalyzer.exception.ConfigFileFormatException;
import org.zyf.javabasic.spring.failureanalyzer.model.ConfigFileFormatErrorInfo;
import javax.annotation.PostConstruct;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import static org.zyf.javabasic.spring.failureanalyzer.model.ConfigFileFormatErrorInfo.ErrorType.*;
/**
 * @program: zyfboot-javabasic
 * @description: 指定配置文件驗(yàn)證邏輯
 * @author: zhangyanfeng
 * @create: 2024-05-02 20:12
 **/
@Component
public class ConfigFileFormatChecker {
    @Autowired
    private ResourceLoader resourceLoader;
    @PostConstruct
    public void checkConfigFileFormat() {
        String fileName = "report-config.xml";
        Resource resource = resourceLoader.getResource("classpath:" + fileName);
        if (!resource.exists()) {
            throw new ConfigFileFormatException(new ConfigFileFormatErrorInfo(true, null, fileName));
        }
        Element root = null;
        try (InputStream inputStream = resource.getInputStream()) {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(new InputSource(inputStream));
            // 獲取根元素
            root = document.getDocumentElement();
        } catch (Exception e) {
            throw new ConfigFileFormatException(new ConfigFileFormatErrorInfo(true, OTHER, fileName));
        }
        // 檢查 dataSource Bean 定義
        checkDataSourceDefinition(root, fileName);
        // 檢查報(bào)告生成器定義
        checkReportGeneratorDefinition(root, fileName);
    }
    private void checkDataSourceDefinition(Element root, String fileName) {
        // 獲取 dataSource 元素
        NodeList dataSourceList = root.getElementsByTagName("bean");
        for (int i = 0; i < dataSourceList.getLength(); i++) {
            Element dataSourceElement = (Element) dataSourceList.item(i);
            String id = dataSourceElement.getAttribute("id");
            if ("dataSource".equals(id)) {
                // 獲取 driverClassName 屬性
                String driverClassName = dataSourceElement.getElementsByTagName("property")
                        .item(0)
                        .getAttributes()
                        .getNamedItem("value")
                        .getNodeValue();
                // 獲取 url 屬性
                String url = dataSourceElement.getElementsByTagName("property")
                        .item(1)
                        .getAttributes()
                        .getNamedItem("value")
                        .getNodeValue();
                // 獲取 username 屬性
                String username = dataSourceElement.getElementsByTagName("property")
                        .item(2)
                        .getAttributes()
                        .getNamedItem("value")
                        .getNodeValue();
                // 獲取 password 屬性
                String password = dataSourceElement.getElementsByTagName("property")
                        .item(3)
                        .getAttributes()
                        .getNamedItem("value")
                        .getNodeValue();
                if (StringUtils.isAnyBlank(driverClassName, url, username, password)) {
                    throw new ConfigFileFormatException(new ConfigFileFormatErrorInfo(false, MISSING_PROPERTY, fileName));
                }
                if (!isPasswordEncrypted(password)) {
                    throw new ConfigFileFormatException(new ConfigFileFormatErrorInfo(false, INVALID_VALUE, fileName));
                }
            }
        }
    }
    private void checkReportGeneratorDefinition(Element root, String fileName) {
        // 獲取 reportGenerator 元素
        NodeList reportGeneratorList = root.getElementsByTagName("bean");
        for (int i = 0; i < reportGeneratorList.getLength(); i++) {
            Element reportGeneratorElement = (Element) reportGeneratorList.item(i);
            String id = reportGeneratorElement.getAttribute("id");
            if ("reportGenerator".equals(id)) {
                // 獲取 dataSource 屬性的引用
                String dataSourceRef = reportGeneratorElement.getElementsByTagName("property")
                        .item(0)
                        .getAttributes()
                        .getNamedItem("ref")
                        .getNodeValue();
                if (StringUtils.isAnyBlank(dataSourceRef)) {
                    throw new ConfigFileFormatException(new ConfigFileFormatErrorInfo(false, MISSING_PROPERTY, fileName));
                }
            }
        }
    }
    private boolean isPasswordEncrypted(String password) {
        // 檢查密碼是否已加密,這里可以根據(jù)具體加密方式進(jìn)行驗(yàn)證
        return password.startsWith("Zyf");
    }
}

接著創(chuàng)建并實(shí)現(xiàn)AbstractFailureAnalyzer,重寫analyze()方法如下:

package org.zyf.javabasic.spring.failureanalyzer.analyzer;
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
import org.springframework.boot.diagnostics.FailureAnalysis;
import org.zyf.javabasic.spring.failureanalyzer.exception.ConfigFileFormatException;
import org.zyf.javabasic.spring.failureanalyzer.model.ConfigFileFormatErrorInfo;
import org.zyf.javabasic.spring.failureanalyzer.model.DescriptionAndAction;
/**
 * @program: zyfboot-javabasic
 * @description: 指定配置文件具體格式要求
 * @author: zhangyanfeng
 * @create: 2024-05-02 20:31
 **/
public class ZYFConfigFileFormatFailureanalyzer extends AbstractFailureAnalyzer<ConfigFileFormatException> {
    @Override
    protected FailureAnalysis analyze(Throwable rootFailure, ConfigFileFormatException cause) {
        ConfigFileFormatErrorInfo errorInfo = cause.getErrorInfo();
        String description;
        String action;
        if (errorInfo.isFileNotFound()) {
            description = "Configuration file '" + errorInfo.getFileName() + "' not found";
            action = "Check if the configuration file exists.";
        } else {
            DescriptionAndAction descriptionAndAction = errorInfo.getDescriptionAndAction();
            description = descriptionAndAction.getDescription();
            action = descriptionAndAction.getAction();
        }
        return new FailureAnalysis(description, action, cause);
    }
}

spring.factories中增加本次新增驗(yàn)證:

org.springframework.boot.diagnostics.FailureAnalyzer=\
org.zyf.javabasic.spring.failureanalyzer.analyzer.ZYFConfigFileFailureAnalyzer,\
org.zyf.javabasic.spring.failureanalyzer.analyzer.ZYFConfigFileFormatFailureanalyzer

但是我實(shí)際report-config.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 數(shù)據(jù)庫連接信息 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/zyf"/>
        <property name="username" value="root"/>
        <property name="password" value="Zsyf2014"/>
    </bean>
    <!-- 報(bào)告生成器 -->
    <bean id="reportGenerator" class="org.zyf.javabasic.spring.beanFactory.ReportGenerator">
        <property name="dataSource" ref="dataSource"/>
        <!-- 其他配置屬性 -->
    </bean>
</beans>

由于數(shù)據(jù)庫加密不正確,故程序啟動(dòng)報(bào)錯(cuò)如下:

六、一些建議

如果確定了需要?jiǎng)?chuàng)建自定義的 FailureAnalyzer 時(shí),必須有幾個(gè)注意事項(xiàng):

  • 確保 FailureAnalyzer 能夠準(zhǔn)確地識(shí)別失敗的原因,避免誤導(dǎo)性的診斷,幫助更快地找到并解決問題。
  • 在診斷中提供盡可能詳細(xì)的信息,包括失敗的具體原因、發(fā)生失敗的位置等。
  • 提供清晰的建議或解決方案,可以包括修復(fù)代碼、調(diào)整配置或執(zhí)行其他操作的建議。

相關(guān)源碼依舊在常用的github地址中。

七、總結(jié)

在本文中,我們深入探討了FailureAnalyzer這一強(qiáng)大的工具,它不僅能幫助我們快速識(shí)別和處理代碼中的錯(cuò)誤,還能極大地提升我們的開發(fā)效率。通過詳細(xì)的實(shí)例分析,我們了解了FailureAnalyzer如何通過自定義邏輯應(yīng)對(duì)不同類型的異常,讓程序員能夠更好地定位問題并迅速找到解決方案。

借助FailureAnalyzer,我們可以在面對(duì)復(fù)雜的錯(cuò)誤時(shí)不再手忙腳亂,而是能夠從容應(yīng)對(duì)。這種能力的提升,不僅讓我們的代碼更加穩(wěn)健,也讓我們?cè)陂_發(fā)過程中保持了更高的生產(chǎn)力和信心。正如我們?cè)谝灾刑岬降?,面?duì)那些不斷“汪汪”作響的錯(cuò)誤,F(xiàn)ailureAnalyzer就像一位貼心的朋友,時(shí)刻陪伴在側(cè),為我們指引方向。

最后,掌握FailureAnalyzer的使用,不僅能幫助我們更有效地處理錯(cuò)誤,還能促使我們?cè)诰幊痰穆贸讨胁粩喑砷L。希望本文能激勵(lì)你在未來的項(xiàng)目中充分利用這一工具,持續(xù)提升自己的代碼質(zhì)量和開發(fā)技能。讓我們一起,邁向更加穩(wěn)定和高效的編程世界!

到此這篇關(guān)于Spring Boot的FailureAnalyzer機(jī)制的文章就介紹到這了,更多相關(guān)Spring Boot FailureAnalyzer機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 圖文詳解Java中的字節(jié)輸入與輸出流

    圖文詳解Java中的字節(jié)輸入與輸出流

    在Java中所有數(shù)據(jù)都是使用流讀寫的,流是一組有序的數(shù)據(jù)序列,將數(shù)據(jù)從一個(gè)地方帶到另一個(gè)地方,這篇文章主要給大家介紹了關(guān)于Java中字節(jié)輸入與輸出流的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • Java中的ArrayList、LinkedList、HashSet等容器詳解

    Java中的ArrayList、LinkedList、HashSet等容器詳解

    這篇文章主要介紹了Java中的ArrayList、LinkedList、HashSet等容器詳解,集合表示一組對(duì)象,稱為其元素,有些集合允許重復(fù)元素,而另一些則不允許,有些是有序的,有些是無序的,需要的朋友可以參考下
    2023-08-08
  • Java經(jīng)典排序算法之希爾排序詳解

    Java經(jīng)典排序算法之希爾排序詳解

    這篇文章主要為大家詳細(xì)介紹了Java經(jīng)典排序算法之希爾排序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Spring boot+beetl+i18n國際化處理的方法

    Spring boot+beetl+i18n國際化處理的方法

    這篇文章主要介紹了Spring boot+beetl+i18n國際化處理的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Springboot集成jsp及部署服務(wù)器實(shí)現(xiàn)原理

    Springboot集成jsp及部署服務(wù)器實(shí)現(xiàn)原理

    這篇文章主要介紹了Springboot集成jsp及部署服務(wù)器實(shí)現(xiàn)原理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 一文帶你了解Spring中@Enable開頭注解的使用

    一文帶你了解Spring中@Enable開頭注解的使用

    前面的文章給大家介紹?Spring?的重試機(jī)制的時(shí)候有提到過?Spring?有很多?@Enable?開頭的注解,平時(shí)在使用的時(shí)候也沒有注意過為什么會(huì)有這些注解,今天就給大家介紹一下
    2022-09-09
  • 了解Java虛擬機(jī)JVM的基本結(jié)構(gòu)及JVM的內(nèi)存溢出方式

    了解Java虛擬機(jī)JVM的基本結(jié)構(gòu)及JVM的內(nèi)存溢出方式

    這篇文章主要介紹了Java虛擬機(jī)JVM的基本結(jié)構(gòu)及JVM的內(nèi)存溢出方式,涉及到Java內(nèi)存分配相關(guān)方面的知識(shí),需要的朋友可以參考下
    2016-01-01
  • Java代碼塊與代碼加載順序原理詳解

    Java代碼塊與代碼加載順序原理詳解

    這篇文章主要介紹了Java代碼塊與代碼加載順序原理詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 詳解 Java中日期數(shù)據(jù)類型的處理之格式轉(zhuǎn)換的實(shí)例

    詳解 Java中日期數(shù)據(jù)類型的處理之格式轉(zhuǎn)換的實(shí)例

    這篇文章主要介紹了詳解 Java中日期數(shù)據(jù)類型的處理之格式轉(zhuǎn)換的實(shí)例的相關(guān)資料,日期以及時(shí)間格式處理,在Java中時(shí)間格式一般會(huì)涉及到的數(shù)據(jù)類型包括Calendar類和Date類,需要的朋友可以參考下
    2017-08-08
  • Java的集合LinkedHashSet詳解

    Java的集合LinkedHashSet詳解

    這篇文章主要介紹了Java的集合LinkedHashSet詳解,LinkedHashSet介于HashSet和TreeSet之間,它也是一個(gè)hash表,但是同時(shí)維護(hù)了一個(gè)雙鏈表來記錄插入的順序,需要的朋友可以參考下
    2023-09-09

最新評(píng)論

四子王旗| 拉萨市| 鸡东县| 荃湾区| 大城县| 彭水| 兴国县| 开鲁县| 安溪县| 阿荣旗| 化州市| 红桥区| 方正县| 永泰县| 揭东县| 宜州市| 巴南区| 开平市| 渭源县| 和龙市| 松溪县| 宜春市| 祁阳县| 新安县| 安远县| 临汾市| 报价| 霍林郭勒市| 莱阳市| 满洲里市| 枣强县| 九寨沟县| 江永县| 逊克县| 盖州市| 普定县| 抚顺县| 阳山县| 温宿县| 应城市| 札达县|