最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot之自定義啟動異常堆棧信息打印方式

 更新時間:2021年08月09日 08:38:52   作者:weixin_36276193  
這篇文章主要介紹了SpringBoot之自定義啟動異常堆棧信息打印方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

在SpringBoot項目啟動過程中,當(dāng)一些配置或者其他錯誤信息會有一些的規(guī)范的提示信息

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

Description:

Web server 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.

在SpringBoot 中其實現(xiàn)原理是什么,我們該如何自定義異常信息呢

1、SpringBoot異常處理的源碼分析

在springboot啟動的核心方法run中會加載所有的SpringBootExceptionReporter

 exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
     new Class[] { ConfigurableApplicationContext.class }, context);

調(diào)用了getSpringFactoriesInstances方法

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
  ClassLoader classLoader = getClassLoader();
  // Use names and ensure unique to protect against duplicates
  Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
  List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
  AnnotationAwareOrderComparator.sort(instances);
  return instances;
 }

其主要通過Spring的Factories機制來加載

public ConfigurableApplicationContext run(String... args) {
  StopWatch stopWatch = new StopWatch();
  stopWatch.start();
  ConfigurableApplicationContext context = null;
  Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
  configureHeadlessProperty();
  SpringApplicationRunListeners listeners = getRunListeners(args);
  listeners.starting();
  try {
   ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
   ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
   configureIgnoreBeanInfo(environment);
   Banner printedBanner = printBanner(environment);
   context = createApplicationContext();
   exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
     new Class[] { ConfigurableApplicationContext.class }, context);
   prepareContext(context, environment, listeners, applicationArguments, printedBanner);
   refreshContext(context);
   afterRefresh(context, applicationArguments);
   stopWatch.stop();
   if (this.logStartupInfo) {
    new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
   }
   listeners.started(context);
   callRunners(context, applicationArguments);
  }
  catch (Throwable ex) {
  //異常捕獲中,向用戶打印異常信息
   handleRunFailure(context, ex, exceptionReporters, listeners);
   throw new IllegalStateException(ex);
  }

  try {
   listeners.running(context);
  }
  catch (Throwable ex) {
   handleRunFailure(context, ex, exceptionReporters, null);
   throw new IllegalStateException(ex);
  }
  return context;
 }

在try catch中,catch會打印異常信息

private void handleRunFailure(ConfigurableApplicationContext context, Throwable exception,
   Collection<SpringBootExceptionReporter> exceptionReporters, SpringApplicationRunListeners listeners) {
  try {
   try {
    handleExitCode(context, exception);
    if (listeners != null) {
     listeners.failed(context, exception);
    }
   }
   finally {
    reportFailure(exceptionReporters, exception);
    if (context != null) {
     context.close();
    }
   }
  }
  catch (Exception ex) {
   logger.warn("Unable to close ApplicationContext", ex);
  }
  ReflectionUtils.rethrowRuntimeException(exception);
 }
 private void reportFailure(Collection<SpringBootExceptionReporter> exceptionReporters, Throwable failure) {
  try {
   for (SpringBootExceptionReporter reporter : exceptionReporters) {
    if (reporter.reportException(failure)) {
     registerLoggedException(failure);
     return;
    }
   }
  }
  catch (Throwable ex) {
   // Continue with normal handling of the original failure
  }
  if (logger.isErrorEnabled()) {
   logger.error("Application run failed", failure);
   registerLoggedException(failure);
  }
 }

遍歷exceptionReporters,打印日常信息

SpringBootExceptionReporter-

SpringBootExceptionReporter是一個回調(diào)接口,用于支持對SpringApplication啟動錯誤的自定義報告。里面就一個報告啟動失敗的方法。

其實現(xiàn)類:org.springframework.boot.diagnostics.FailureAnalyzers

用于觸發(fā)從spring.factories加載的FailureAnalyzer和FailureAnalysisReporter實例。

2、如何自定義異常信息

/**
 * <p>
 *
 * <p>
 *
 * @author: xuwd
 * @time: 2020/11/16 10:52
 */
public class WannaStopException extends RuntimeException {
}

自定義異常信息打印

public class StopFailureAnalyzer
        extends AbstractFailureAnalyzer<WannaStopException> {
    @Override
    protected FailureAnalysis analyze(Throwable rootFailure, WannaStopException cause) {
        for (StackTraceElement stackTraceElement : cause.getStackTrace()) {
            if (stackTraceElement.getClassName().equals("com.pigx.demo.Config21")) {
                return new FailureAnalysis("A想停止", "別要A了", cause);
            }
        }
        return null;
    }
}

接下來令他生效,通過上面分析可以可看出需要通過AutoConfigurationImportSelector,類似于自定義SpringBoot Starter AutoConfiguration的形式,我們需要在META-INF/spring.factories文件內(nèi)進(jìn)行定義,如下所示:

https://juejin.im/post/6844903956208943111

接著在合適的地方拋出WannaStopException 異常

總結(jié)

在springboot 啟動過程中會先對異常信息進(jìn)行補捕獲,對進(jìn)行日志格式處理的日志進(jìn)行處理;其核心是通過SpringBootExceptionReporter回調(diào)及sping-spi bean的管理。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringSecurity實現(xiàn)圖形驗證碼功能的實例代碼

    SpringSecurity實現(xiàn)圖形驗證碼功能的實例代碼

    Spring Security 的前身是 Acegi Security ,是 Spring 項目組中用來提供安全認(rèn)證服務(wù)的框架。這篇文章主要介紹了SpringSecurity實現(xiàn)圖形驗證碼功能,需要的朋友可以參考下
    2018-10-10
  • 關(guān)于Java Interface接口的簡單練習(xí)題

    關(guān)于Java Interface接口的簡單練習(xí)題

    這篇文章主要給大家分享的是關(guān)于Java Interface接口的簡單練習(xí)題,難度不算大,但是要有一個清晰的邏輯建立接口和鏈接Java類。下面來看看文章的詳細(xì)介紹吧,需要的朋友可以參考一下
    2021-11-11
  • springMVC之HandlerExceptionResolver使用

    springMVC之HandlerExceptionResolver使用

    這篇文章主要介紹了springMVC之HandlerExceptionResolver使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • mybatis-plus條件構(gòu)造器的操作代碼

    mybatis-plus條件構(gòu)造器的操作代碼

    mybatis-plus提供了AbstractWrapper抽象類,提供了很多sql語法支持的方法,比如模糊查詢,比較,區(qū)間,分組查詢,排序,判斷空,子查詢等等,方便我們用面向?qū)ο蟮姆绞饺崿F(xiàn)sql語句,本文重點給大家介紹mybatis-plus條件構(gòu)造器的操作代碼,感興趣的朋友一起看看吧
    2022-03-03
  • MybatisPlusInterceptor實現(xiàn)sql攔截器超詳細(xì)教程

    MybatisPlusInterceptor實現(xiàn)sql攔截器超詳細(xì)教程

    這篇文章主要給大家介紹了關(guān)于MybatisPlusInterceptor實現(xiàn)sql攔截器超詳細(xì)教程的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • 詳解Java多線程編程中LockSupport類的線程阻塞用法

    詳解Java多線程編程中LockSupport類的線程阻塞用法

    LockSupport類提供了park()和unpark()兩個方法來實現(xiàn)線程的阻塞和喚醒,下面我們就來詳解Java多線程編程中LockSupport類的線程阻塞用法:
    2016-07-07
  • 詳解Spring Data JPA系列之投影(Projection)的用法

    詳解Spring Data JPA系列之投影(Projection)的用法

    本篇文章主要介紹了詳解Spring Data JPA系列之投影(Projection)的用法,具有一定的參考價值,有興趣的可以了解一下
    2017-07-07
  • Java虛擬機之對象創(chuàng)建過程與類加載機制及雙親委派模型

    Java虛擬機之對象創(chuàng)建過程與類加載機制及雙親委派模型

    這篇文章主要給大家介紹了關(guān)于Java虛擬機之對象創(chuàng)建過程與類加載機制及雙親委派模型的相關(guān)資料,本文通過示例代碼以及圖文介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2021-11-11
  • Java日常練習(xí)題,每天進(jìn)步一點點(22)

    Java日常練習(xí)題,每天進(jìn)步一點點(22)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-07-07
  • Java多線程并發(fā)之ReentrantLock

    Java多線程并發(fā)之ReentrantLock

    這篇文章主要介紹了Java?多線程并發(fā)ReentrantLock,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2023-04-04

最新評論

徐汇区| 白朗县| 金华市| 图木舒克市| 孟津县| 台湾省| 鱼台县| 兴义市| 寿宁县| 方正县| 德州市| 日土县| 凤庆县| 加查县| 东明县| 曲阜市| 顺平县| 宾川县| 年辖:市辖区| 绩溪县| 昌江| 论坛| 文化| 若羌县| 乐都县| 鹤庆县| 洛阳市| 葵青区| 黄浦区| 炉霍县| 翁源县| 潜山县| 太原市| 蒲城县| 民权县| 镇江市| 天全县| 石景山区| 澄城县| 安国市| 牟定县|