zoukankan      html  css  js  c++  java
  • Spring Boot小组件

    前言

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

     
  • 相关阅读:
    nullnullConnecting with WiFi Direct 与WiFi直接连接
    nullnullUsing WiFi Direct for Service Discovery 直接使用WiFi服务发现
    nullnullSetting Up the Loader 设置装载机
    nullnullDefining and Launching the Query 定义和启动查询
    nullnullHandling the Results 处理结果
    装置输出喷泉装置(贪心问题)
    数据状态什么是事务?
    停止方法iOS CGD 任务开始与结束
    盘文件云存储——金山快盘
    函数标识符解决jQuery与其他库冲突的方法
  • 原文地址:https://www.cnblogs.com/imyijie/p/12695098.html
Copyright © 2011-2022 走看看