SpringBoot核心机制四、FailureAnalyzer
发布日期:2021-04-30 21:01:11 浏览次数:131 分类:精选文章

本文共 7807 字,大约阅读时间需要 26 分钟。

Spring Boot 错误分析器:从零开始到深入理解

在开发Spring Boot应用时,遇到异常是不可避免的。默认的堆栈信息虽然有助于排查问题,但对于开发者来说,Spring Boot提供的友好错误提示功能更加宝贵。通过自定义错误分析器,我们可以让程序在抛出异常时,给出更详细的描述和修复建议,从而显著提升应用的健壮性。本文将从零开始,带你深入了解Spring Boot的错误分析机制。

一、自定义错误分析器

在Spring Boot中,错误分析器的主要作用是捕捉异常并提供修复建议。我们可以通过以下步骤实现自定义错误分析器:

  • 抛出异常:在Spring Boot应用的主方法中抛出一个异常。例如,可以抛出一个ArithmeticException,这样可以测试我们的分析器是否能正确识别和处理该异常。
  • @SpringBootApplicationpublic class P1Application implements CommandLineRunner {    public static void main(String[] args) {        final SpringApplication application = new SpringApplication(P1Application.class);        application.run(args);    }    @Autowired    private ApplicationContext applicationContext;    @Override    public void run(String... args) throws Exception {        // 在这里会抛出一个ArithmeticException异常        int i = 1 / 0;    }}
    1. 创建自定义错误分析器:创建一个继承自AbstractFailureAnalyzer的新类。这个类将处理ArithmeticException异常,并返回一个包含描述、动作和原因的FailureAnalysis对象。
    2. public class ArithmeticFailureAnalyzer extends AbstractFailureAnalyzer
      { @Override protected FailureAnalysis analyze(Throwable rootFailure, ArithmeticException cause) { return new FailureAnalysis(cause.getMessage(), "Calculate Error.", cause); }}
      1. 注册错误分析器:在spring.factories文件中注册自定义的错误分析器。这样Spring Boot将在遇到异常时使用我们的分析器。
      2. org.springframework.boot.diagnostics.FailureAnalyzer=org.roy.failureAnalyzer.ArithmeticFailureAnalyzer
        1. 测试自定义错误分析器:运行应用时,查看错误提示是否已更新为我们自定义的友好格式。
        2. 二、Spring Boot 错误分析机制解读

          了解Spring Boot的错误分析机制有助于更好地定制和扩展它。让我们深入解读其核心实现:

        3. SpringApplication的run方法:Spring Boot应用的启动逻辑集中在SpringApplication.run方法中。这个方法负责初始化上下文,并处理可能的异常。
        4. @SpringBootApplicationpublic class P1Application implements CommandLineRunner {    public static void main(String[] args) {        final SpringApplication application = new SpringApplication(P1Application.class);        application.run(args);    }    @Autowired    private ApplicationContext applicationContext;    @Override    public void run(String... args) throws Exception {        // 在这里会抛出一个ArithmeticException异常        int i = 1 / 0;    }}
          1. 处理运行失败:当程序运行失败时,handleRunFailure方法会被调用。这个方法负责收集异常信息并进行处理。
          2. private void handleRunFailure(ConfigurableApplicationContext context, Throwable exception, SpringApplicationRunListeners listeners) {    try {        handleExitCode(context, exception);        if (listeners != null) {            listeners.failed(context, exception);        }    } finally {        reportFailure(getExceptionReporters(context), exception);        if (context != null) {            context.close();        }    }}
            1. 获取异常报告器getExceptionReporters方法负责加载Spring Boot的错误报告器配置。默认配置下,会加载FailureAnalyzers
            2. private Collection
              getExceptionReporters(ConfigurableApplicationContext context) { try { return getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[0], context); } catch (Throwable ex) { return Collections.emptyList(); }}
              1. 报告异常reportFailure方法遍历所有注册的错误报告器,并调用其reportException方法打印异常信息。
              2. private void reportFailure(Collection
                exceptionReporters, Throwable failure) { try { for (SpringBootExceptionReporter reporter : exceptionReporters) { if (reporter.reportException(failure)) { registerLoggedException(failure); return; } } } catch (Throwable ex) { // 继续处理原始失败 } if (logger.isErrorEnabled()) { logger.error("Application run failed", failure); registerLoggedException(failure); }}
                1. 默认错误报告器:默认的错误报告器是LoggingFailureAnalysisReporter。它负责将错误信息格式化为友好的日志。
                2. private String buildMessage(FailureAnalysis failureAnalysis) {    StringBuilder builder = new StringBuilder();    builder.append(String.format("%n%n"));    builder.append(String.format("***************************%n"));    builder.append(String.format("APPLICATION FAILED TO START%n"));    builder.append(String.format("***************************%n%n"));    builder.append(String.format("Description:%n%n"));    builder.append(String.format("%s%n", failureAnalysis.getDescription()));    if (StringUtils.hasText(failureAnalysis.getAction())) {        builder.append(String.format("%nAction:%n%n"));        builder.append(String.format("%s%n", failureAnalysis.getAction()));    }    return builder.toString();}

                  三、Spring Boot 中的核心实现

                  了解Spring Boot中默认提供的错误分析器实现,可以帮助我们更好地定制和扩展错误提示功能。以下是Spring Boot中默认配置的错误分析器:

                3. 失败分析器:Spring Boot提供了多种失败分析器,用于处理不同类型的异常。
                4. org.springframework.boot.diagnostics.FailureAnalyzer=\    org.springframework.boot.context.config.ConfigDataNotFoundFailureAnalyzer,\    org.springframework.boot.context.properties.IncompatibleConfigurationFailureAnalyzer,\    org.springframework.boot.context.properties.NotConstructorBoundInjectionFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.BeanDefinitionOverrideFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer,\    org.springframework.boot.diagnostics.analyzer.PatternParseFailureAnalyzer,\    org.springframework.boot.liquibase.LiquibaseChangelogMissingFailureAnalyzer
                  1. 失败分析报告器:默认的失败分析报告器是LoggingFailureAnalysisReporter。它负责将错误信息格式化为友好的日志。
                  2. private String buildMessage(FailureAnalysis failureAnalysis) {    StringBuilder builder = new StringBuilder();    builder.append(String.format("%n%n"));    builder.append(String.format("***************************%n"));    builder.append(String.format("APPLICATION FAILED TO START%n"));    builder.append(String.format("***************************%n%n"));    builder.append(String.format("Description:%n%n"));    builder.append(String.format("%s%n", failureAnalysis.getDescription()));    if (StringUtils.hasText(failureAnalysis.getAction())) {        builder.append(String.format("%nAction:%n%n"));        builder.append(String.format("%s%n", failureAnalysis.getAction()));    }    return builder.toString();}

                    四、扩展Spring Boot 错误分析器

                    Spring Boot的错误分析机制非常灵活,可以通过配置自定义实现来扩展其功能。例如,可以将错误信息打印到日志文件中,或者集成到第三方日志分析工具中。

                  3. 自定义报告器:创建一个新的FailureAnalysisReporter实现类,定义自己的reportException方法。
                  4. public class MyCustomFailureReporter implements FailureAnalysisReporter {    @Override    public boolean reportException(FailureAnalysis failureAnalysis) {        // 将failureAnalysis转换为自定义的日志格式        logger.info("应用启动失败:{}", failureAnalysis.getDescription());        logger.info("建议操作:{}", failureAnalysis.getAction());        return true;    }}
                    1. 注册自定义报告器:在spring.factories文件中注册自定义的报告器。
                    2. org.springframework.boot.diagnostics.FailureAnalysisReporter=org.roy.customReporter.MyCustomFailureReporter
                      1. 集成第三方工具:将错误信息打印到日志文件中,可以使用Logback等日志框架的轮转功能。
                      2. ${LOG_DIR}/application.log
                        %-36.36ms %-5p [%-5.5s] [%-45.45c] %m%n

                        通过以上方法,我们可以根据实际需求对Spring Boot的错误分析机制进行定制和扩展,从而构建一个更加健壮和智能的应用系统。

    上一篇:CentOS-6.5 安装Oracle11g详细步骤
    下一篇:在IDEA的EE项目中导入第三方jar包

    发表评论

    最新留言

    第一次来,支持一个
    [***.219.124.196]2026年05月24日 06时43分32秒