SpringBoot FailureAnalyzer实例使用教程
目录
- SpringBoot自定义FailureAnalyzer
- FailureAnalyzer
- FailureAnalysis对象
- PortInUseFailureAnalyzer
- AbstractFailureAnalyzer
- FailureAnalyzer-自定义
- 定义异常类
- 实现FailureAnalyzer
- 添加spring.factories
- 验证测试
- 测试代码
- 验证结果
SpringBoot自定义FailureAnalyzer
今天在学习Spring Boot 源码的过程中,在spring.factories 文件中无意中发现了FailureAnalyzer 这个接口。由于之前没有接触过,今天来学习一下 FailureAnalyzer 接口的作用。
在学习FailureAnalyzer之前, 我们先看以下截图
相信Spring的开发者,或多或少的遇到过以上的错误。由于端口占用阻止了应用程序启动,这跟今天的主角有关系。Spring Boot 应用程序启动时,FailureAnalyzer接口拦截启动过程中发生的异常,并终止启动。
FailureAnalyzer
核心接口定义
package org.springframework.boot.diagnostics; /** * 该接口用户分析异常堆栈信息,将其转换为用户可读的对象信息,通常情况下,对象包含错误描述和建议. * @since 1.4.0 */ @FunctionalInterface public interface FailureAnalyzer { /** * 返回异常错误的分析对象,或null * @param failure the failure * @return the analysis or {@code null} */ FailureAnalysis analyze(Throwable failure); }
FailureAnalyzer 定义为函数式接口,因此可以使用Lambda表达式实现接口,简化代码开发。从定义上可以看出接收 Throwable 类型的参数,返回失败分析对象 - 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抽象类,最终实现了端口占用报错信息的分析。
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; } /** * 重新定义钩子方法,将参数与泛型对象关联,具象化了每一个子类需要实现的功能 */ 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接口定义的功能。该抽象类实现了Exception对象与失败分析实现类一一对应的功能。如
//PortInUseFailureAnalyzer 负责解析 PortInUseException 异常 class PortInUseFailureAnalyzer extends AbstractFailureAnalyzer<PortInUseException>{ ... }
FailureAnalyzer-自定义
上面提到过具体的失败分析类,是跟每一种Exception类对应的,那么我们从定义异常类开始
定义异常类
package com.andy.spring.boot.docker.exception; public class CustomApplicationException extends RuntimeException { public CustomApplicationException(String msg){ super(msg); } }
异常类定义完毕后,需要定义解析该异常的失败分析类
实现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, 自定义失败分析器出现了...!", "Ummm... 啥都不做,删库跑路", cause); } }
接下来,需要Spring
添加spring.factories
接下来,需要Spring Boot 框架识别失败分析。SPI机制出场,在resources/META-INF目录下创建spring.factories文件,内容如下
org.springframework.boot.diagnostics.FailureAnalyzer=com.andy.spring.boot.docker.analyzer.CustomApplicationFailureAnalyzer
验证测试
测试代码
到目前为止,万事具备,只欠东风。我们需要在应用启动时,抛出自定义异常即可
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 初始化异常"); } }
验证结果
重新启动应用程序,出现以下错误
到此这篇关于SpringBoot FailureAnalyzer实例使用教程的文章就介绍到这了,更多相关SpringBoot FailureAnalyzer内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!