SpringBoot项⽬启动失败的解决⽅案
Spring Boot 项⽬是不是经常失败,显⽰⼀⼤堆的错误信息,如端⼝重复绑定时会打印以下异常:
***************************
APPLICATION FAILED TO START
***************************
Description:
Embedded servlet container failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
这个⼤家应该很熟悉了吧!
错误信息⼤家都能看懂,但很不友好,那么,Spring Boot 是怎么实现这样⼀个异常错误信息输出的呢?今天栈长分享⼀个Spring Boot 启动失败的简单易懂的玩法,让新来的实习⽣ 1 秒都能看出问题。
如果你对 Spring Boot 还不是很熟悉,或者只是会简单的使⽤,那还是建议你深⼊学习下吧,推荐这个 Spring Boot 学习仓库,欢迎 Star 关注:
Failure Analyzers 介绍
Spring Boot 中注册了许多 "Failure Analyzers",即 "失败分析器",Spring Boot 中的启动失败的场景都是由这些失败分析器拦截处理的。
Spring Boot 提供了FailureAnalyzers接⼝:
package org.springframework.boot.diagnostics;
/**
* A {@code FailureAnalyzer} is used to analyze a failure and provide diagnostic
* information that can be displayed to the user.
*
* @author Andy Wilkinson
* @since 1.4.0
*/
@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);
}
这个接⼝的⽬的就是:分析启动失败异常并显⽰给⽤户有⽤的诊断信息。
Spring Boot 内置注册的所有失败分析器在这个⽂件⾥⾯:
/org/springframework/boot/spring-boot/2.3.5.RELEASE/spring-boot-2.3.5.RELEASE-sources.jar!/META-
INF/spring.factories
注册的所有失败分析器列表:
# Failure Analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.t.properties.NotConstructorBoundInjectionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanDefinitionOverrideFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,\springboot中文
org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer
再回到上⾯的端⼝重复绑定启动失败异常,就是注册了PortInUseFailureAnalyzer这个失败分析器,可以看到PortInUseFailureAnalyzer失败分析器就在注册列表⾥⾯。
再来看下PortInUseFailureAnalyzer 的源码:
/**
* A {@code FailureAnalyzer} that performs analysis of failures caused by a
* {@code PortInUseException}.
*
* @author Andy Wilkinson
*/
class PortInUseFailureAnalyzer extends AbstractFailureAnalyzer<PortInUseException> {
@Override
protected FailureAnalysis analyze(Throwable rootFailure, PortInUseException cause) {
return new FailureAnalysis("Web server failed to start. Port " + Port() + " was already in use.",
"Identify and stop the process that's listening on port " + Port() + " or configure this "
+ "application to listen on another port.",
cause);
}
}
只要应⽤启动过程上抛出了PortInUseException异常就会被这个失败分析器拦截并输出可读性的错误信息,现在知道绑定重复绑定错误是怎么输出的了。
⾃定义 Failure Analyzers
从内置的失败分析器中可以发现,所有的分析器都继承了这个抽象基类是:AbstractFailureAnalyzer,它实现了FailureAnalyzer 接⼝,⼀般基于这个抽象基类就可以实现⾃定义失败分析器的扩展。
下⾯栈长通过两个⽰例带⼤家了解下,如何扩展或者⾃定义⼀个 FailureAnalyzer。
1、重写端⼝失败分析器
⽐如说上⾯的PortInUseFailureAnalyzer输出内容是英⽂的,不是很直观的看出,我们可以⾃⼰实现⼀个中⽂的端⼝失败分析器。很简单,创建⼀个失败分析器继承 AbstractFailureAnalyzer 抽象类即可:
package cn.javastack.springboot.features.analyzer;
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
import org.springframework.boot.diagnostics.FailureAnalysis;
import org.springframework.boot.web.server.PortInUseException;
public class PortInUseFailureAnalyzer extends AbstractFailureAnalyzer<PortInUseException> {
@Override
protected FailureAnalysis analyze(Throwable rootFailure, PortInUseException cause) {
return new FailureAnalysis("你启动的端⼝ " + Port() + " 被占⽤了.",
"快检查下端⼝ " + Port() + " 被哪个程序占⽤了,或者强制杀掉进程.",
cause);
}
}
重写analyze⽅法,并返回⼀个FailureAnalysis对象,FailureAnalysis类的三个主要信息分别是:
public FailureAnalysis(String description, String action, Throwable cause) {
this.description = description;
this.action = action;
this.cause = cause;
}
即要展⽰的:可读性的错误描述、建议的检查修复动作、原始异常。
然后在⾃⼰的资源⽬录下创建 META-INF/spring.factories ⽂件,内容添加:
org.springframework.boot.diagnostics.FailureAnalyzer=\
cn.javastack.springboot.features.analyzer.PortInUseFailureAnalyzer
启动输出:
***************************
APPLICATION FAILED TO START
***************************
Description:
你启动的端⼝ 8080 被占⽤了.
Action:
快检查下端⼝ 8080 被哪个程序占⽤了,或者强制杀掉进程.
这样重新实现⼀下是不是要清楚多了?实习⽣都能看懂!
2、⾃定义失败分析器
下⾯再来⾃定义⼀个全新的失败分析器,让⼤家能更清楚的认识失败分析器。
我们在创建 Bean 的过程中⼿动抛出⼀个⾃定义的异常:
@Bean
public CommandLineRunner commandLineRunner(){
throw new JavastackException("Java技术栈异常");
}
添加⼀个失败分析器拦截该异常:
package cn.javastack.springboot.features.analyzer;
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
import org.springframework.boot.diagnostics.FailureAnalysis;
public class JavastackFailureAnalyzer extends AbstractFailureAnalyzer<JavastackException> {
@Override
protected FailureAnalysis analyze(Throwable rootFailure, JavastackException cause) {
return new FailureAnalysis("Java技术栈发⽣异常了……",
"赶快去检查⼀下吧!",
cause);
}
}
添加注册:
org.springframework.boot.diagnostics.FailureAnalyzer=\
cn.javastack.springboot.features.analyzer.PortInUseFailureAnalyzer,\
cn.javastack.springboot.features.analyzer.JavastackFailureAnalyzer
启动输出:
***************************
APPLICATION FAILED TO START
***************************
Description:
Java技术栈发⽣异常了……
Action:
赶快去检查⼀下吧!
如果不注册该失败分析器,这个⾃定义的异常就不会被内置的失败分析器拦截,就会输出⼤堆的异常信息,使⽤失败分析器能很直观的看出是什么错误及怎么修复这个错误。
总结
Spring Boot 提供的失败分析器以友好的错误信息和修复建议代替了⼤堆的错误异常信息,可以帮助我们更直观的定位应⽤启动故障,你学会了吗?
本⽂的所有⽰例源代码都已上传到了 Github:
欢迎⼤家 Star 关注,后续会不断更新。
以上就是Spring Boot 项⽬启动失败的解决⽅案的详细内容,更多关于Spring Boot 项⽬启动失败的资料请关注其它相关⽂章!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。