springboot之FailureAnalyzer

2020-11-19 15:21:16 浏览数 (1)

springboot之FailureAnalyzer

在这篇文章中,我们将探究springboot中的FailureAnalyzer(故障分析器),我们还将了解在springboot应用中创建自定义FailureAnalyzer。

介绍

大多数情况下,当我们在服务器启动时遇到异常时,我们需要非常仔细地分析,以便在尝试修复它之前理解出什么问题。

通过FailureAnalyzer,springboot提供了一种在启动时拦截异常的方法,并将它们转换为人性化的格式(不必翻阅整个异常堆栈信息)。springboot自带了许多从应用程序上下文相关异常开始的FailureAnalyzer故障分析器。

这里有一个例子,8080端口已经被使用,当我们试图在8080端口运行我们的springboot应用时,PortInUseFailureAnalyzer截获这个异常并提供了一个更具可读性和用户友好的错误消息。

*************************** APPLICATION FAILED TO START *************************** Description: The Tomcat connector configured to listen on port 8080 failed to start. The port may already be in use or the connector may be misconfigured. Action: Verify the connector's configuration, identify and stop any process that's listening on port 8080, or configure this application to listen on another port.

以下是springboot提供的几个常用的FailureAnalyzer列表:

  1. PortInUseFailureAnalyzer
  2. NoUniqueBeanDefinitionFailureAnalyzer
  3. BeanCurrentlyInCreationFailureAnalyzer

你可以通过查看springboot的org.springframework.boot.diagnostics包找到完整的FailureAnalyzer列表。

springboot提供了一种简单的方法来创建我们自己的自定义FailureAnalyzer。

1

创建自定义FailureAnalyzer

为了创建我们自己的自定义FailureAnalyzer,我们可以使用AbstractFailureAnalyzer作为方便的扩展点,AbstractFailureAnalyzer将检查是否存在指定的异常,并允许我们的自定义分析器处理它。

我们在springboot应用中为下述用例创建一个自定义FailureAnalyze:

  1. 尝试为给定的依赖注入一个不同的bean
  2. 当我们尝试注入它时,Spring将抛出BeanNotOfRequiredTypeException异常,因为我们正在尝试注入不同的bean

下面试简单的FailureAnalyzer代码:

public class CustomFailureAnalyzer extends AbstractFailureAnalyzer<BeanNotOfRequiredTypeException> { /** * Returns an analysis of the given {@code failure}, or {@code null} if no analysis * was possible. * * @param rootFailure the root failure passed to the analyzer * @param cause the actual found cause * @return the analysis or {@code null} */ @Override protected FailureAnalysis analyze(Throwable rootFailure, BeanNotOfRequiredTypeException cause) { String message ="####################### This is a custom fail Message ################ %n" getDescription(cause); return new FailureAnalysis(message , (String)null, cause); } private String getDescription(BeanNotOfRequiredTypeException ex) { StringWriter description = new StringWriter(); PrintWriter printer = new PrintWriter(description); printer.printf( "The bean %s could not be injected" "due to %s", ex.getBeanName(), ex.getRequiredType().getName()); return description.toString(); } }

重点在于analyze()方法,它将被触发,springboot将传递一个Throwable对象以及用例(也就是Spring抛出的异常)。

2

注册自定义FailureAnalyzer

我们需要一种特殊的方法来用springboot注册自定义FailureAnalyzer,以便springboot能够在系统引发异常的情况下调用自定义FailureAnalyzer,需要使用META-INF文件夹中的spring.factories属性文件来注册它。

如果META-INF文目录或者spring.factories文件不存在,需要手动创建,若要注册自定义FailureAnalyzer,在spring.factories中添加以下条目:

org.springframework.boot.diagnostics.FailureAnalyzer= com.umeshawasthi.failureanalyzer.CustomFailureAnalyzer

如果有多个FailureAnalyzer,您可以使用逗号分隔将其注册为多个条目:

org.springframework.boot.diagnostics.FailureAnalyzer= com.umeshawasthi.failureanalyzer.CustomFailureAnalyzer, com.umeshawasthi.failureanalyzer.CustomFailureAnalyzer1

到这里,我们设置了所有的自定义FailureAnalyzer并且可以测试了。

3

FailureAnalyzer实际应用

我在示例中创建了2个类,内容如下:

public class AdminDAO { public void helloAdmin(){ System.out.println("Hello Admin"); } } @Repository("adminDAO") public class AdminDAOImpl { public void setupAdmin(){ //default implimentation } }

创建一个控制器,并且将AdminDAO以adminDAO属性注入进去:

@RestController public class HelloWorldController { @Resource(name = "adminDAO") private AdminDAO adminDAO; //some methods }

如果运行springboot应用程序 ,Spring将尝试在AdminDAO中注入AdminDAOImpl类型的adminDao,因为类型不兼容,Spring将抛出BeanNotOfRequiredTypeException,在当前用例中,springboot将检查并确定注册了一个有效的FailureAnalyzer,并将信息传递给注册的FailureAnalyzer。

在我们的例子中,我们已经注册了CustomFailureAnalyzer来处理这种情况,springboot将把这个信息传递给我们的自定义FailureAnalyzer以产生更加友好的消息。

这是我们运行应用程序时的输出:

*************************** APPLICATION FAILED TO START *************************** Description: ################# This is a custom fail Message ################ %nThe bean adminDAO could not be injecteddue to com.umeshawasthi.service.AdminDAO

总结

在本文中,我们探究了springboot提供的一个有趣的特性,我们看到了springboot FailureAnalyzer的工作原理以及如何创建我们自己的自定义FailureAnalyzer。

0 人点赞