Spring Boot 项目启动失败的解决方案
SpringBoot项目是不是经常失败,显示一大堆的错误信息,如端口重复绑定时会打印以下异常:
*************************** APPLICATIONFAILEDTOSTART *************************** Description: Embeddedservletcontainerfailedtostart.Port8080wasalreadyinuse. Action: Identifyandstoptheprocessthat'slisteningonport8080orconfigurethisapplicationtolistenonanotherport.
这个大家应该很熟悉了吧!
错误信息大家都能看懂,但很不友好,那么,SpringBoot是怎么实现这样一个异常错误信息输出的呢?今天栈长分享一个SpringBoot启动失败的简单易懂的玩法,让新来的实习生1秒都能看出问题。
如果你对SpringBoot还不是很熟悉,或者只是会简单的使用,那还是建议你深入学习下吧,推荐这个SpringBoot学习仓库,欢迎Star关注:
https://github.com/javastacks/spring-boot-best-practice
FailureAnalyzers介绍
SpringBoot中注册了许多"FailureAnalyzers",即"失败分析器",SpringBoot中的启动失败的场景都是由这些失败分析器拦截处理的。
SpringBoot提供了FailureAnalyzers接口:
packageorg.springframework.boot.diagnostics; /** *A{@codeFailureAnalyzer}isusedtoanalyzeafailureandprovidediagnostic *informationthatcanbedisplayedtotheuser. * *@authorAndyWilkinson *@since1.4.0 */ @FunctionalInterface publicinterfaceFailureAnalyzer{ /** *Returnsananalysisofthegiven{@codefailure},or{@codenull}ifnoanalysis *waspossible. *@paramfailurethefailure *@returntheanalysisor{@codenull} */ FailureAnalysisanalyze(Throwablefailure); }
这个接口的目的就是:分析启动失败异常并显示给用户有用的诊断信息。
SpringBoot内置注册的所有失败分析器在这个文件里面:
/org/springframework/boot/spring-boot/2.3.5.RELEASE/spring-boot-2.3.5.RELEASE-sources.jar!/META-INF/spring.factories
注册的所有失败分析器列表:
#FailureAnalyzers org.springframework.boot.diagnostics.FailureAnalyzer=\ org.springframework.boot.context.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,\ 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{@codeFailureAnalyzer}thatperformsanalysisoffailurescausedbya *{@codePortInUseException}. * *@authorAndyWilkinson */ classPortInUseFailureAnalyzerextendsAbstractFailureAnalyzer{ @Override protectedFailureAnalysisanalyze(ThrowablerootFailure,PortInUseExceptioncause){ returnnewFailureAnalysis("Webserverfailedtostart.Port"+cause.getPort()+"wasalreadyinuse.", "Identifyandstoptheprocessthat'slisteningonport"+cause.getPort()+"orconfigurethis" +"applicationtolistenonanotherport.", cause); } }
只要应用启动过程上抛出了PortInUseException异常就会被这个失败分析器拦截并输出可读性的错误信息,现在知道绑定重复绑定错误是怎么输出的了。
自定义FailureAnalyzers
从内置的失败分析器中可以发现,所有的分析器都继承了这个抽象基类是:AbstractFailureAnalyzer,它实现了FailureAnalyzer接口,一般基于这个抽象基类就可以实现自定义失败分析器的扩展。
下面栈长通过两个示例带大家了解下,如何扩展或者自定义一个FailureAnalyzer。
1、重写端口失败分析器
比如说上面的PortInUseFailureAnalyzer输出内容是英文的,不是很直观的看出,我们可以自己实现一个中文的端口失败分析器。
很简单,创建一个失败分析器继承AbstractFailureAnalyzer抽象类即可:
packagecn.javastack.springboot.features.analyzer; importorg.springframework.boot.diagnostics.AbstractFailureAnalyzer; importorg.springframework.boot.diagnostics.FailureAnalysis; importorg.springframework.boot.web.server.PortInUseException; publicclassPortInUseFailureAnalyzerextendsAbstractFailureAnalyzer{ @Override protectedFailureAnalysisanalyze(ThrowablerootFailure,PortInUseExceptioncause){ returnnewFailureAnalysis("你启动的端口"+cause.getPort()+"被占用了.", "快检查下端口"+cause.getPort()+"被哪个程序占用了,或者强制杀掉进程.", cause); } }
重写analyze方法,并返回一个FailureAnalysis对象,FailureAnalysis类的三个主要信息分别是:
publicFailureAnalysis(Stringdescription,Stringaction,Throwablecause){ this.description=description; this.action=action; this.cause=cause; }
即要展示的:可读性的错误描述、建议的检查修复动作、原始异常。
然后在自己的资源目录下创建META-INF/spring.factories文件,内容添加:
org.springframework.boot.diagnostics.FailureAnalyzer=\ cn.javastack.springboot.features.analyzer.PortInUseFailureAnalyzer
启动输出:
*************************** APPLICATIONFAILEDTOSTART *************************** Description: 你启动的端口8080被占用了. Action: 快检查下端口8080被哪个程序占用了,或者强制杀掉进程.
这样重新实现一下是不是要清楚多了?实习生都能看懂!
2、自定义失败分析器
下面再来自定义一个全新的失败分析器,让大家能更清楚的认识失败分析器。
我们在创建Bean的过程中手动抛出一个自定义的异常:
@Bean publicCommandLineRunnercommandLineRunner(){ thrownewJavastackException("Java技术栈异常"); }
添加一个失败分析器拦截该异常:
packagecn.javastack.springboot.features.analyzer; importorg.springframework.boot.diagnostics.AbstractFailureAnalyzer; importorg.springframework.boot.diagnostics.FailureAnalysis; publicclassJavastackFailureAnalyzerextendsAbstractFailureAnalyzer{ @Override protectedFailureAnalysisanalyze(ThrowablerootFailure,JavastackExceptioncause){ returnnewFailureAnalysis("Java技术栈发生异常了……", "赶快去检查一下吧!", cause); } }
添加注册:
org.springframework.boot.diagnostics.FailureAnalyzer=\ cn.javastack.springboot.features.analyzer.PortInUseFailureAnalyzer,\ cn.javastack.springboot.features.analyzer.JavastackFailureAnalyzer
启动输出:
*************************** APPLICATIONFAILEDTOSTART *************************** Description: Java技术栈发生异常了…… Action: 赶快去检查一下吧!
如果不注册该失败分析器,这个自定义的异常就不会被内置的失败分析器拦截,就会输出大堆的异常信息,使用失败分析器能很直观的看出是什么错误及怎么修复这个错误。
总结
SpringBoot提供的失败分析器以友好的错误信息和修复建议代替了大堆的错误异常信息,可以帮助我们更直观的定位应用启动故障,你学会了吗?
本文的所有示例源代码都已上传到了Github:
https://github.com/javastacks/spring-boot-best-practice
欢迎大家Star关注,后续会不断更新。
以上就是SpringBoot项目启动失败的解决方案的详细内容,更多关于SpringBoot项目启动失败的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。