Spring Boot 老啟動失敗,這次再也不怕了!
阿新 • • 發佈:2021-03-02
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 關注:
> https://github.com/javastacks/spring-boot-best-practice
## 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.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 {@code FailureAnalyzer} that performs analysis of failures caused by a
* {@code PortInUseException}.
*
* @author Andy Wilkinson
*/
class PortInUseFailureAnalyzer extends AbstractFailure