Spring Boot小组件 - FailureAnalyzer

Foreword

A Spring Boot application occasionally fails to start for some reason, at this time Spring Boot will friendly output a text similar to this, telling you what happened and even what action should be taken:

***************************

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.

How did this happen? Perhaps the first idea is that Spring Boot will construct such a complete exception and output where the problem occurs. In fact, this is not the case. Spring Boot provides a unified interface for problem analysis and diagnosis. This is the org.springframework.boot.diagnostics.FailureAnalyzer interface.

The source code version used in this article is 2.2.2.RELEASE, if there is any discrepancy, please check whether the version is inconsistent.

Where to start

It is known that the Spring Boot project is SpringApplication#run(java.lang.String...)started by calling . We will find that when the startup process throws an exception, it is handled like this:

catch (Throwable ex) {
	handleRunFailure(context, ex, exceptionReporters, listeners);
	// ...
}

Observe that the found method parameter exceptionReportersis used to report the exception handling. Looking back to find its definition, it is found that it SpringFactoriesLoader#loadFactoryNamesloads the SpringBootExceptionReporterimplementation class defined in spring.factories in META-INF under the classpath .

There is generally only FailureAnalyzersone implementation class, and the processing inside is also very simple: by SpringFactoriesLoaderloading into all defined FailureAnalyzerimplementations, and then preparing a little bit. When analyzing abnormalities, it is good to traverse all to FailureAnalyzersee who can analyze the problem. After the analysis, the results of the analysis are reported, and FailureAnalysisReporterall the implementation classes are loaded and then reported one by one. There is usually only one, that is, we see the output log in the "Preface" LoggingFailureAnalysisReporter.

SpringFactoriesLoader is similar to Java's native SPI, which can be achieved by writing a configuration file to find a service for an interface.

Be your own

If you make your own component, you may encounter situations where you need to handle exceptions and provide recommendations to users.

We define an exception

public class WannaStopException extends RuntimeException {
}

We define a Bean that will throw an exception under certain (full) types (parts)

@Service
public class A {
    public A() {
        throw new WannaStopException();
    }
}

We define a FailureAnalyzerspecial deal with thisWannaStopException

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 helps us find specific anomalies

Next we have to put StopFailureAnalyzerit spring.factoriesin and add it in resources / META-INF / spring.factories (built by ourselves)

org.springframework.boot.diagnostics.FailureAnalyzer=\
  com.example.flowable.StopFailureAnalyzer 

Launch this application, you can see the following output

***************************

APPLICATION FAILED TO START

***************************

Description:

A wants to stop

Action:

Don't ask for A

In addition, it is noted that it FailureAnalysisReportercan be used to alert the development or perform some automatic repair operations (such as automatic rollback).

Guess you like

Origin www.cnblogs.com/imyijie/p/12695098.html