SpringBoot啟動源碼解析(一)

来源:https://www.cnblogs.com/lslime/archive/2022/09/27/16734521.html
-Advertisement-
Play Games

特殊說明:第一章只包含了 初始化上下文,初始化監聽器列表,發佈springboot啟動事件 相關內容 其中一部分代碼 /** * Run the Spring application, creating and refreshing a new * {@link ApplicationContext ...


特殊說明:第一章只包含了 初始化上下文,初始化監聽器列表,發佈springboot啟動事件 相關內容

其中一部分代碼
/**
* Run the Spring application, creating and refreshing a new
* {@link ApplicationContext}.
* @param args the application arguments (usually passed from a Java main method)
* @return a running {@link ApplicationContext}
*/
public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    DefaultBootstrapContext bootstrapContext = createBootstrapContext();
    ConfigurableApplicationContext context = null;
    configureHeadlessProperty();
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);
}

 

1、初始化一個計時器,並開始計時

StopWatch stopWatch = new StopWatch();
stopWatch.start();

其實是用來統計應用啟動耗時的。

實現原理為記錄下開始時間和結束時間,相減即可。

 

2、初始化啟動上下文

private DefaultBootstrapContext createBootstrapContext() {
    DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
    this.bootstrapRegistryInitializers.forEach((initializer) -> initializer.initialize(bootstrapContext));
    return bootstrapContext;
}

new一個預設的上下文

 

3、設置該應用程式,即使沒有檢測到顯示器,也允許其啟動

configureHeadlessProperty();

private void configureHeadlessProperty() {
    System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS,
                       System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless)));
}

設置了一個名為java.awt.headless的系統屬性。

為true時,即使沒有顯示器,也可以啟動。

例如linux伺服器。

 

4、獲取SpringApplicationRunListener的實現類

SpringApplicationRunListeners listeners = getRunListeners(args);

進入getRunListeners方法

private SpringApplicationRunListeners getRunListeners(String[] args) {
    Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
    return new SpringApplicationRunListeners(logger,
                                             getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args), 
                                             this.applicationStartup);
}

①、獲取了一個class數組types

其中的元素分別為:SpringApplication和String數組的class對象。在後續反射初始化對象時,types用於獲取到目標的構造方法。

②、獲取SpringApplicationRunListener實例對象

其中,調用了getSpringFactoriesInstances方法。該方法的目的為:獲取SpringApplicationRunListener介面的所有實現類對象。

在後續的啟動過程中,交由listeners發佈的事件,實際上是遍歷其內部管理的SpringApplicationRunListener對象列表進行發佈的。

需要註意的是,通過getSpringFactoriesInstances方法獲取到的SpringApplicationRunListener類型的對象有且僅有一個:EventPublishingRunListener實例對象。

③、通過獲取到的SpringApplicationRunListener實例,創建一個SpringApplicationRunListeners對象並返回。

第一和第三步比較簡單。

讓我們關註下第二步,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;
}

首先通過getClassLoader方法,獲取到預設的類載入器,

然後通過SpringFactoriesLoader.loadFactoryNames(type, classLoader),獲取SpringApplicationRunListener所有的實現類名稱,

最後創建SpringApplicationRunListener介面的所有實現類對象,排序並返回。

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 探索密碼學的奇妙之旅。介紹HMAC單向散列消息認證碼、加鹽。使用golang crypto包實現HMAC生成與驗證,重放攻擊演示。 ...
  • ###一、簡介 什麼是分散式爬蟲? 分散式爬蟲就是把一個爬蟲任務放到多台機器上去運行,提高爬取效率 但是每台機器運行同一套代碼,都在各自的任務和去重隊列,等於各爬各的,最終爬的數據是相同的 因此需要提供一個公共的去重隊列和公共的任務隊列,多台機器都在共用的隊列中去調度和去重,然後分別爬取 原來scr ...
  • 可視化打包 exe,這個神器絕了 auto-py-to-exe 是一個用於將Python程式打包成可執行文件的圖形化工具。本文就是主要介紹如何使用 auto-py-to-exe 完成 python 程式打包。auto-py-to-exe 基於 pyinstaller ,相比於 pyinstaller ...
  • 如何將編寫的c語言程式打包成exe可執行文件呢? 以前我們寫程式很多是在編輯器上,讓編輯起來編譯運行我們的程式。如果想將其打包成exe可執行文件該如何做? 我這裡推薦使用codeBlocks的gcc命令,因為比較簡單。像vs這種編輯器就像是一把屠龍刀。功能過於複雜,需要註意的很多。如何適用codeB ...
  • 《Go 精進之路》 讀書筆記。簡要記錄自己打五角星的部分,方便複習鞏固。目前看到p120 Go 語言遵從的設計哲學為組合 垂直組合:類型嵌入,快速讓一個類型復用其他類型已經實現的能力,實現功能的垂直擴展。 水平組合:介面實現鴨子類型。 變數名字中不要帶有類型信息 userSlice []*User ...
  • 怎麼借鑒開源代碼來打造一些自身面對的問題解決方案?也許有一些Demo來進行回答演示或許更為貼近地氣些。這裡打算寫一些玩轉源碼為主題的文字來實踐的回答,最近在看P3C的一些源碼,那就從這開始吧。 ...
  • 什麼是 Session 會話? 1、Session 就一個介面(HttpSession)。 2、Session 就是會話。它是用來維護一個客戶端和伺服器之間關聯的一種技術。 3、每個客戶端都有自己的一個 Session 會話。 4、Session 會話中,我們經常用來保存用戶登錄之後的信息。 如何創 ...
  • Spring中AOP的底層原理就是動態代理模式,所以我們在這裡對代理模式進行學習。 一、代理模式 1.什麼是代理 代理,顧名思義,就是一個人代替另一個人去做他需要做的事情。代理是一種設計模式,具體實現就是一個類代替某個類去實現功能。 我們舉一個例子: 我要租房子,我可以找房東直接租房子。同樣我可以找 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...