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.flowable.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可以用来向开发进行报警,或者进行一些自动修复操作(如自动回滚)等。

原文地址:https://www.cnblogs.com/imyijie/p/12695098.html

时间: 2024-10-12 16:43:17

Spring Boot小组件 - FailureAnalyzer的相关文章

最近做了一个Spring Boot小项目,大家帮忙找找bug吧, http://www.dbeetle.cn

最近做了一个Spring Boot小项目,网站顶部有源码地址,欢迎大家访问 http://www.dbeetle.cn 欢迎各位访问,提出意见,找找bug 网站说明 甲壳虫社区(Beetle Community) 一个开源的问答社区.论坛博客,您可以提出自己的问题.发布自己的文章.和其他用户交流 目前功能有第三方登陆.查看.发布.评论.消息通知.顶置.一键已读.搜索等 后续会不断更新完善,欢迎大家提供更好的建议 使用技术 Spring Boot.Mybatis.Thymeleaf.BootStr

spring boot 四大组件之Starter

1.概述 依赖管理是任何复杂项目的关键方面.手动完成这些操作并不理想; 你花在它上面的时间越多,你在项目的其他重要方面所花费的时间就越少. 构建Spring Boot启动器是为了解决这个问题.Starter POM是一组方便的依赖描述符,您可以在应用程序中包含这些描述符.您可以获得所需的所有Spring和相关技术的一站式服务,而无需搜索示例代码,并复制粘贴依赖描述符. 2.The Web Starter首先,我们来看看开发REST服务; 我们可以使用像Spring MVC,Tomcat和Jack

Spring Boot 最佳实践(一)快速入门

一.关于Spring Boot 在开始了解Spring Boot之前,我们需要先了解一下Spring,因为Spring Boot的诞生和Spring是息息相关的,Spring Boot是Spring发展到一定程度的一个产物,但并不是Spring的替代品,Spring Boot是为了让程序员更好的使用Spring.说到这里可能有些人会迷糊,那到底Spring和Spring Boot有着什么样的联系呢? 1.Spring发展史 在开始之前我们先了解一下Spring,Spring的前身是interfa

使用Ratpack和Spring Boot打造高性能的JVM微服务应用

使用Ratpack和Spring Boot打造高性能的JVM微服务应用 这是我为InfoQ翻译的文章,原文地址:Build High Performance JVM Microservices with Ratpack & Spring Boot,InfoQ上的中文地址:使用Ratpack与Spring Boot构建高性能JVM微服务. 在微服务天堂中Ratpack和Spring Boot是天造地设的一对.它们都是以开发者为中心的运行于JVM之上的web框架,侧重于生产率.效率以及轻量级部署.他

使用Ratpack与Spring Boot构建高性能JVM微服务

在微服务天堂中Ratpack和Spring Boot是天造地设的一对.它们都是以开发者为中心的运行于JVM之上的web框架,侧重于生产率.效率以及轻量级部署.他们在服务程序的开发中带来了各自的好处.Ratpack通过一个高吞吐量.非阻塞式的web层提供了一个反应式编程模型,而且对应用程序结构的定义和HTTP请求过程提供了一个便利的处理程序链:Spring Boot集成了整个Spring生态系统,为应用程序提供了一种简单的方式来配置和启用组件.Ratpack和Spring Boot是构建原生支持计

创建Spring Boot项目

使用材料:IDEA spring initializr,或者 maven项目直接构建 建立好的项目结构如图 所有组件包需要和Application同一级别目录. 新建步骤: 1.使用IDEA Spring initializr 2.配置一些基础信息 3.确定初期导入的包,建议项目推荐两个,一个是web模块,一个是jdbc模块. 4.完成创建 完了之后IDEA会自动生成一个Spring项目,查看pom文件,并添加jackson,作为rest端口的Map to Json 转换 <?xml versi

Spring Boot 嵌入式 Tomcat 文件上传、url 映射虚拟路径

1.Java web 应用开发完成后如果是导入外置的 Tomcat 的 webapps 目录的话,那么上传的文件可以直接的放在应用的 web 目录下去就好了,浏览器可以很方便的进行访问. 2.Spring Boot 默认使用嵌入式 Tomcat ,将来打包成可执行 Jar 文件进行部署,显然打成 jar 包后,总不可能再将上传的文件放在 resources 目录下去了. 3.Spring Boot 于是提供了 url 地址匹配本地虚拟路径的功能: 1)上传文件到服务器,服务器将文件保存到了本地,

Spring Boot Log 日志使用教程

我们编写任何 Spring Boot 程序,可能绕不开的就是 log 日志框架(组件). 在大多数程序员眼中日志是用来定位问题的.这很重要. 本项目源码下载 注意本项目提供的源码已在后期重新编写,有部分日期描述不一致. 如果你只是想知道 Spring boot log 如何使用,请直接观看 3.2 使用 Spring Boot Logback 1 Log 日志概述 1.1 Log 日志组件能干什么 日志能干的事情很多,对于学习程序,测试的工程师来说,日志能够定位问题,解决问题,是最大的功能点.

spring boot入门小案例

spring boot 入门小案例搭建 (1) 在Eclipse中新建一个maven project项目,目录结构如下所示: cn.com.rxyb中存放spring boot的启动类,application.properties中放spring boot相关配置 (2) 在pom.xml中加入spring boot 依赖包 (3)在cn.com.rxyb中新建启动类APP 1 package cn.com.rxyb; 2 import org.springframework.boot.Spri