SpringBoot為什么使用new RuntimeException() 來獲取調用棧?

?為什么不直接使用?Thread.currentThread().getStackTrace()

這確實看起來有點“奇怪”或者“繞”,但其實這是 Java 中一種非常常見、巧妙且合法的技巧,用于在運行時動態獲取當前代碼的調用棧信息。

Spring 選擇用 new RuntimeException().getStackTrace() 是有原因的,主要有以下幾點區別:

特性new Exception().getStackTrace()Thread.currentThread().getStackTrace()
調用棧更詳細? 包括每個類和方法名? 可能只包含類名,不包含具體方法名
性能開銷略高(需要構造異常對象)較低
精確性? 更精確地定位到調用者? 在某些 JVM 實現中可能不準確
使用場景需要精確調用棧時(如框架內部)快速查看線程堆棧(調試、日志等)

所以 Spring 框架為了確保能夠準確找到調用鏈中的 main 方法所在類,選擇了第一種方式。

	public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");// 注冊啟動類this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));// 推斷應用類型,一般是webthis.webApplicationType = WebApplicationType.deduceFromClasspath();// 注冊初始化器 (擴展接口)setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));// 注冊監聽器  (擴展接口)setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 找到啟動的主方法入口this.mainApplicationClass = deduceMainApplicationClass();}private Class<?> deduceMainApplicationClass() {try {// 使用RuntimeException().getStackTrace()獲取調用棧StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();for (StackTraceElement stackTraceElement : stackTrace) {if ("main".equals(stackTraceElement.getMethodName())) {return Class.forName(stackTraceElement.getClassName());}}}catch (ClassNotFoundException ex) {// Swallow and continue}return null;}
public enum WebApplicationType {/*** 不需要嵌入式 web 容器,不是 web 應用*/NONE,/*** 需要嵌入式的 web 容器(如 Tomcat, Jetty)*/SERVLET,/*** 使用 reactive web stack(如 Netty + WebFlux)*/REACTIVE;
}

補充:

public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;configureHeadlessProperty();SpringApplicationRunListeners listeners = getRunListeners(args);// 監聽器觸發1: EventPublishingRunListener 會發布 ApplicationStartingEventlisteners.starting();try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);// 準備應用所需的環境信息ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);configureIgnoreBeanInfo(environment);// 打印Banner的logo和日志Banner printedBanner = printBanner(environment);context = createApplicationContext();// 準備應用上下文,包括設置環境、注冊初始 Bean 定義、觸發上下文準備完成事件prepareContext(context, environment, listeners, applicationArguments, printedBanner);// 刷新應用上下文 (核心)refreshContext(context);// 應用上下文刷新后的一些操作afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}// 監聽器觸發2:ApplicationReadyListener發布 ApplicationReadyEventlisteners.started(context);// 調用所有 CommandLineRunner 和 ApplicationRunner 接口實現類的 run 方法callRunners(context, applicationArguments);}catch (Throwable ex) {handleRunFailure(context, ex, listeners);throw new IllegalStateException(ex);}try {// 監聽器觸發3:對于 running(context) 并沒有直接對應的事件被發布,執行一些運行時的監控或通知邏輯,比如通知外部系統應用已就緒listeners.running(context);}catch (Throwable ex) {handleRunFailure(context, ex, null);throw new IllegalStateException(ex);}return context;}
  • starting()?- 觸發?ApplicationStartingEvent
  • environmentPrepared()?- 觸發?ApplicationEnvironmentPreparedEvent
  • contextPrepared()?- 觸發?ApplicationContextInitializedEvent
  • contextLoaded()?- 觸發?ApplicationPreparedEvent
  • started(context)?- 觸發?ApplicationReadyEvent

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/89170.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89170.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89170.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

小白成長之路-haproxy負載均衡

文章目錄一、概述1、HAProxy簡介2、HAProxy特點和優點&#xff1a;3、HAProxy保持會話的三種解決方法4、HAProxy的balance 8種負載均衡算法1&#xff09;RR&#xff08;Round Robin&#xff09;2&#xff09;LC&#xff08;Least Connections&#xff09;3&#xff09;SH&#…

Kafka 與 RocketMQ 消息確認機制對比分析

目錄 生產者消息確認機制 Kafka 生產者 ACK 機制 RocketMQ 生產者確認機制 消費者消息確認機制 Kafka 消費者確認機制 RocketMQ 消費者確認機制 核心差異對比 選型建議 消息確認機制是分布式消息中間件的核心功能之一&#xff0c;它直接關系到消息傳遞的可靠性和系統性能…

C/C++---rdbuf()函數

在C中&#xff0c;rdbuf() 是I/O流庫中的一個核心成員函數&#xff0c;主要用于訪問和操作流對象的緩沖區。這個函數在底層數據處理、流重定向以及自定義流操作等場景中應用廣泛。下面將從多個方面詳細解析 rdbuf() 函數。 基本概念與函數原型 rdbuf() 是 std::basic_ios 類的成…

【LLM】從零到一構建一個小型LLM--MiniGPT

從零到一構建一個小型LLM (Small Language Model)暫時起名為MiniGPT。這個模型將專注于因果語言建模 (Causal Language Modeling)&#xff0c;這是許多現代LLM&#xff08;如GPT系列&#xff09;的核心預訓練任務。模型設計&#xff1a; 我們設計的模型是一個僅包含解碼器 (Dec…

網絡安全威脅下的企業困境與破局技術實踐

前言&#xff1a;網絡安全威脅下的企業困境 在數字化轉型的浪潮中&#xff0c;企業對信息技術的依賴程度日益加深&#xff0c;但隨之而來的網絡安全威脅也愈發嚴峻。據統計&#xff0c;全球每年因網絡安全事件造成的經濟損失高達數萬億美元&#xff0c;其中中小企業更是成為了網…

[RAG system] 信息檢索器 | BM25 Vector | Pickle格式 | HybridRetriever重排序

第六章&#xff1a;信息檢索器 在上一章中&#xff0c;我們成功完成了知識庫攝入流程。這是巨大的進步~ 我們精心準備了文檔"塊"&#xff08;類似獨立的索引卡&#xff09;&#xff0c;并將其存儲在兩套智能歸檔系統中&#xff1a;向量數據庫&#xff08;用于基于含…

Android 高通平臺修改音頻參數效果文件-優化音頻效果

Android 高通平臺如何音頻效果 修改音頻參數效果文件-優化音頻效果 按如下方式修改。 開發云 - 一站式云服務平臺 diff --git a/vendor/qcom/proprietary/mm-audio/audcal/family-b/acdbdata//MTP/workspaceFile.qwsp b/vendor/qcom/proprietary/mm-audio/audcal/family-b/acdb…

Install Docker Engine on UbuntuMySQL

Install Docker Engine on Ubuntu&&MySQL安裝docker安裝mysql客戶端連接數據庫我真氣鼠了&#xff0c;今天得到一個血淚的教訓&#xff0c;以后一定看官方文檔&#xff01;&#xff01;&#xff01;學的課用的centos&#xff0c;指令全是yum&#xff0c;我這邊不通用&a…

智能人體感應模塊HC-SR501應用指南---使用esp32

人體熱釋電探頭紅外感應模塊 人體感應開關HC-SR501藍板新款 綠板-淘寶網 HC-SR501 人體紅外感應電子模塊傳感器熱釋電探頭感應開關RD-624-tmall.com天貓 模塊信息 HC-SR501人體感應開關是一種基于紅外線技術的自動控制模塊&#xff0c;廣泛應用于安防、智能家居和自動控制等領…

加速度傳感器方向校準方法

保持平板平放在桌面上&#xff0c;將后置攝像頭保持在平板的左上后方&#xff0c;或者右上后方&#xff0c;此為機器的正方向 1、以一臺重力方向正常的機器做測試&#xff0c;通過DeviceInfoHw這個軟件的加速度測試功能【Accelerometer Test】我們可以知道 X方向數據測試&#…

【OpenHarmonyOS應用開發】

OpenHarmonyOS應用開發1.OpenHarmonyOS應用開發環境安裝2.初始化項目3.連接潤和軟件的開發板套件1.OpenHarmonyOS應用開發環境安裝 進入HarmonyOS下載鴻蒙應用開發工具DevEco Studio 5.0.7.200版本。 雙擊打開下載好的可執行文件&#xff0c;點擊下一步。 如果已經安裝過&am…

50天50個小項目 (Vue3 + Tailwindcss V4) ? | AutoTextEffect(自動打字機)

&#x1f4c5; 我們繼續 50 個小項目挑戰&#xff01;—— AutoTextEffect組件 倉庫地址&#xff1a;https://github.com/SunACong/50-vue-projects 項目預覽地址&#xff1a;https://50-vue-projects.vercel.app/。 利用 Vue 3 的 Composition API 和一些簡單的 CSS 動畫來構…

[RAG] LLM 交互層 | 適配器模式 | 文檔解析器(`docling`庫, CNN, OCR, OpenCV)

第二章&#xff1a;LLM 交互層 在上一章中&#xff0c;我們學習了作為"項目總控"的管道協調器&#xff0c;它負責協調 RAG 系統中各個功能模塊。 其中最重要的協調對象之一&#xff0c;便是負責與大型語言模型&#xff08;LLM&#xff09;進行智能交互的LLM 交互層…

Golang 并發快速上手

文章目錄1. 為什么要用協程&#xff1f;1.1 進程與線程1.2 協程1.3 線程和協程的區別線程協程1.4 Go 協程&#xff08;goroutines&#xff09;和協程&#xff08;coroutines&#xff09;2.Go 協程基本內容2.1 channel2.2 select2.3 future 模式3. 實踐示例3.1 并發處理多個網絡…

ESP32輕松實現UDP無線通信

ESP32支持UDP通信&#xff0c;這是一種輕量級、高效的通信協議&#xff0c;適用于需要快速數據傳輸但對數據可靠性要求不高的場景。以下是關于ESP32如何實現UDP通信的詳細說明&#xff1a; 1. UDP協議簡介及其適用場景 UDP&#xff08;用戶數據報協議&#xff09;是一種無連接的…

Electron實現“僅首次運行時創建SQLite數據庫”

在桌面應用中&#xff0c;SQLite因其輕量、嵌入式特性成為本地存儲的熱門選擇。但若重復初始化數據庫&#xff0c;會導致數據覆蓋或冗余。本文將詳解如何讓Electron應用僅在首次啟動時創建SQLite數據庫&#xff0c;后續啟動直接連接現有庫。一、核心邏輯與實現原理 核心思路&am…

阿里開源AI大模型ThinkSound如何為視頻配上靈魂之聲

目錄 前言 一、當AI解決視頻配音的困境 二、引入“思維鏈”&#xff1a;讓AI像專業音效師一樣思考 三、背后的技術支撐 四、未來ThinkSound會如何改變我們的世界&#xff1f; 總結 &#x1f3ac; 攻城獅7號&#xff1a;個人主頁 &#x1f525; 個人專欄:《AI前沿技術要聞…

圖論(1):多叉樹

多叉樹一、基礎知識1. 圖 & 樹2. 模板2.1 建圖二、簡單循環1. 【模板】樹的路徑求和2. 道路修建&#xff08;改&#xff09;3. 聯合權值4. 毛毛蟲樹三、自頂向下/自底向上1. 醫療中心2. 【模板】樹的直徑3. 【模板】最大子樹和4. 信號放大器一、基礎知識 1. 圖 & 樹 …

樓宇自動化:Modbus 在暖通空調(HVAC)中的節能控制(一)

引言**在當今的建筑領域&#xff0c;樓宇自動化正扮演著愈發關鍵的角色&#xff0c;它致力于提升建筑的舒適度、安全性以及能源效率。而暖通空調&#xff08;HVAC&#xff09;系統作為樓宇自動化中的核心部分&#xff0c;其能耗在整個建筑能耗中占比相當高&#xff0c;據相關數…

【SpringBoot】注冊條件+自動配置原理+自定義starter

注冊條件注入到容器內實體類型對象的屬性都是null&#xff0c;這些對象并沒有什么實際的意義&#xff0c;因為實體類的對象就是來封裝對象的&#xff0c;結果你這些對象中什么都沒有&#xff1b;解決方法是1.給這些屬性賦值然后再注入bean但是這些屬性又是固定的不是很好&#…