<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring Boot 老啟動失敗,這次再也不怕了!

          共 8739字,需瀏覽 18分鐘

           ·

          2021-03-02 14:10

          點擊關(guān)注公眾號,Java干貨及時送達

          Spring Boot 項目是不是經(jīng)常失敗,顯示一大堆的錯誤信息,如端口重復(fù)綁定時會打印以下異常:

          ***************************
          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.

          這個大家應(yīng)該很熟悉了吧!

          錯誤信息大家都能看懂,但很不友好,那么,Spring Boot 是怎么實現(xiàn)這樣一個異常錯誤信息輸出的呢?今天棧長分享一個 Spring Boot 啟動失敗的簡單易懂的玩法。

          如果你對 Spring Boot 還不是很熟悉,或者只是會簡單的使用,那還是建議你深入學(xué)習(xí)下吧,推薦這個 Spring Boot 學(xué)習(xí)倉庫,歡迎 Star 關(guān)注:

          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 內(nèi)置注冊的所有失敗分析器在這個文件里面:

          /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

          再回到上面的端口重復(fù)綁定啟動失敗異常,就是注冊了 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 " + cause.getPort() + " was already in use.",
                      "Identify and stop the process that's listening on port " + cause.getPort() + " or configure this "
                            + "application to listen on another port.",
                      cause);
             }

          }

          只要應(yīng)用啟動過程上拋出了 PortInUseException 異常就會被這個失敗分析器攔截并輸出可讀性的錯誤信息,現(xiàn)在知道綁定重復(fù)綁定錯誤是怎么輸出的了。

          自定義 Failure Analyzers

          從內(nèi)置的失敗分析器中可以發(fā)現(xiàn),所有的分析器都繼承了這個抽象基類是:AbstractFailureAnalyzer,它實現(xiàn)了 FailureAnalyzer 接口,一般基于這個抽象基類就可以實現(xiàn)自定義失敗分析器的擴展。

          下面棧長通過兩個示例帶大家了解下,如何擴展或者自定義一個 FailureAnalyzer。

          1、重寫端口失敗分析器

          比如說上面的PortInUseFailureAnalyzer 輸出內(nèi)容是英文的,不是很直觀的看出,我們可以自己實現(xiàn)一個中文的端口失敗分析器。

          很簡單,創(chuàng)建一個失敗分析器繼承 AbstractFailureAnalyzer 抽象類即可:

          /**
           * 來源微信公眾號:Java技術(shù)棧
           */
          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("你啟動的端口 " + cause.getPort() + " 被占用了.",
                      "快檢查下端口 " + cause.getPort() + " 被哪個程序占用了,或者強制殺掉進程.",
                      cause);
             }

          }

          重寫 analyze 方法,并返回一個 FailureAnalysis 對象,FailureAnalysis 類的三個主要信息分別是:

          public FailureAnalysis(String description, String action, Throwable cause) {
             this.description = description;
             this.action = action;
             this.cause = cause;
          }

          即要展示的:可讀性的錯誤描述、建議的檢查修復(fù)動作、原始異常。

          然后在自己的資源目錄下創(chuàng)建 META-INF/spring.factories 文件,內(nèi)容添加:

          org.springframework.boot.diagnostics.FailureAnalyzer=\
          cn.javastack.springboot.features.analyzer.PortInUseFailureAnalyzer

          啟動輸出:

          ***************************
          APPLICATION FAILED TO START
          ***************************

          Description:

          你啟動的端口 8080 被占用了.

          Action:

          快檢查下端口 8080 被哪個程序占用了,或者強制殺掉進程.

          這樣重新實現(xiàn)一下是不是要清楚多了?實習(xí)生都能看懂!

          2、自定義失敗分析器

          下面再來自定義一個全新的失敗分析器,讓大家能更清楚的認識失敗分析器。

          我們在創(chuàng)建 Bean 的過程中手動拋出一個自定義的異常:

          /**
           * 來源微信公眾號:Java技術(shù)棧
           */
          @Bean
          public CommandLineRunner commandLineRunner(){
              throw new JavastackException("Java技術(shù)棧異常");
          }

          添加一個失敗分析器攔截該異常:

          /**
           * 來源微信公眾號:Java技術(shù)棧
           */
          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技術(shù)棧發(fā)生異常了……",
                      "趕快去檢查一下吧!",
                      cause);
             }

          }

          添加注冊:

          org.springframework.boot.diagnostics.FailureAnalyzer=\
          cn.javastack.springboot.features.analyzer.PortInUseFailureAnalyzer,\
          cn.javastack.springboot.features.analyzer.JavastackFailureAnalyzer

          啟動輸出:

          ***************************
          APPLICATION FAILED TO START
          ***************************

          Description:

          Java技術(shù)棧發(fā)生異常了……

          Action:

          趕快去檢查一下吧!

          如果不注冊該失敗分析器,這個自定義的異常就不會被內(nèi)置的失敗分析器攔截,就會輸出大堆的異常信息,使用失敗分析器能很直觀的看出是什么錯誤及怎么修復(fù)這個錯誤。

          總結(jié)

          Spring Boot 提供的失敗分析器以友好的錯誤信息和修復(fù)建議代替了大堆的錯誤異常信息,可以幫助我們更直觀的定位應(yīng)用啟動故障,你學(xué)會了嗎?

          本文的所有示例源代碼都已上傳到了 Github:

          https://github.com/javastacks/spring-boot-best-practice

          歡迎大家 Star 關(guān)注,后續(xù)會不斷更新。

          學(xué)習(xí)更多 Spring Boot 教程,請關(guān)注公眾號Java技術(shù)棧,在后臺回復(fù):boot,歷史 Spring Boot 教程我都整理好了。

          最后,別忘了點在看、轉(zhuǎn)發(fā)哦,需要你的鼓勵~

          版權(quán)申明:本文系公眾號 "Java技術(shù)棧" 原創(chuàng),原創(chuàng)實屬不易,轉(zhuǎn)載、引用本文內(nèi)容請注明出處,禁止抄襲、洗稿,請自重,尊重他人勞動成果和知識產(chǎn)權(quán)。






          關(guān)注Java技術(shù)??锤喔韶?/strong>



          戳原文,獲取精選面試題!
          瀏覽 71
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  四季AV一区二区凹凸懂色 | 中国一级毛片视频 | 日韩欧美在线专区 | 在线观看的毛片网站 | 熟女一区二区 |