• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

SpringBoot打印详细启动异常信息

springboot 搞代码 4年前 (2022-01-09) 33次浏览 已收录 0个评论

SpringBoot在项目启动时如果遇到异常并不能友好的打印出具体的堆栈错误信息,我们只能查看到简单的错误消息,以致于并不能及时解决发生的问题,针对这个问题SpringBoot提供了故障分析仪的概念(failure-analyzer),内部根据不同类型的异常提供了一些实现,我们如果想自定义该怎么去做?

FailureAnalyzer

SpringBoot提供了启动异常分析接口FailureAnalyzer,该接口位于org.springframework.boot.diagnosticspackage内。内部仅提供一个分析的方法,源码如下所示:

@FunctionalInterface
public interface FailureAnalyzer {

    /**
     * Returns an analysis of the given {@code failure}, or {@code null} if no analysis
     * was possible.
     * @param failure the failure
     * @return the analysis or {@code null}
     */
    FailureAnalysis analyze(Throwable failure);

}

接口会把遇到的异常对象实例Throwable failure交付给实现类,实现类进行自定义处理。

AbstractFailureAnalyzer

AbstractFailureAnalyzer是FailureAnalyzer的基础实现抽象类,实现了FailureAnalyzer定义的analyze(Throwable failure)方法,并提供了一个指定异常类型的抽象方法analyze(Throwable rootFailure, T cause),源码如下所示:

public abstract class AbstractFailureAnalyzer<T extends Throwable> implements FailureAnalyzer {

    @Override
    public FailureAnalysis analyze(Throwable failure) {
        T cause = findCause(failure, getCauseType());
        if (cause != null) {
            return analyze(failure, cause);
        }
        return null;
    }

    /**
     * Returns an analysis of the given {@code rootFailure}, 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}
     */
    protected abstract FailureAnalysis analyze(Throwable rootFailure, T cause);

    /**
     * Return the cause type being handled by the analyzer. By default the class generic
     * is used.
     * @return the cause type
     */
    @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;
    }

}

通过AbstractFailureAnalyzer源码我们可以看到,它在实现于FailureAnalyzer的接口方法内进行了特殊处理,根据getCauseType()方法获取当前类定义的第一个泛型类型,也就是我们需要分析的指定异常类型。

获取泛型异常类型后根据方法findCause判断Throwable是否与泛型异常类型匹配,如果匹配直接返回给SpringBoot进行注册处理。

SpringBoot提供的分析实现

SpringBoot内部通过实现AbstractFailureAnalyzer抽象类定义了一系列的针对性异常类型的启动分析,如下图所示:

指定异常分析

SpringBoot内部提供的启动异常分析都是指定具体的异常类型实现的,最常见的一个错误就是端口号被占用(PortInUseException),虽然SpringBoot内部提供一个这个异常的启动分析,我们也是可以进行替换这一异常分析的,我们只需要创建PortInUseException异常的AbstractFailureAnalyzer,并且实现类注册给SpringBoot即可,实现自定义如下所示:

/**
 * 端口号被占用{@link PortInUseException}异常启动分析
 *
 * @author 恒宇少年
 */
public class PortInUseFailureAnalyzer extends AbstractFailureAnalyzer<PortInUseException> {
    /**
     * logger instance
     */
    static<i>本文来源gaodai$ma#com搞$代*码*网</i> Logger logger = LoggerFactory.getLogger(PortInUseFailureAnalyzer.class);

    @Override
    protected FailureAnalysis analyze(Throwable rootFailure, PortInUseException cause) {
        logger.error("端口被占用。", cause);
        return new FailureAnalysis("端口号:"   cause.getPort()   "被占用", "PortInUseException", rootFailure);
    }
}

注册启动异常分析


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:SpringBoot打印详细启动异常信息

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址