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

Spring Boot 應(yīng)用程序啟動時執(zhí)行完整流程(最新推薦)

 更新時間:2025年11月20日 15:39:47   作者:阿薩德528號  
本文給大家介紹關(guān)于Spring Boot應(yīng)用程序啟動時main方法的完整執(zhí)行流程,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧

關(guān)于Spring Boot 應(yīng)用程序啟動時 main 方法的完整執(zhí)行流程。我會按照方法調(diào)用的核心順序進(jìn)行描述,并解釋每個關(guān)鍵方法的作用。

核心流程總覽

在Spring Boot應(yīng)用中,我們通常會寫一個包含main方法的類,并調(diào)用SpringApplication.run。
示例代碼:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

整個啟動過程可以概括為:構(gòu)造 SpringApplication 對象 -> 執(zhí)行 run 方法 -> 啟動內(nèi)嵌服務(wù)器 -> 完成應(yīng)用啟動。

第一階段:SpringApplication實例化

執(zhí)行方法:new SpringApplication(primarySources)

  1. 執(zhí)行 this(null, primarySources)

    • 作用:調(diào)用內(nèi)部的構(gòu)造器。
    • 最主要的部分是 WebApplicationType.deduceFromClasspath() 方法:
      • 這個方法的作用是:根據(jù)類路徑下存在的類來推斷應(yīng)用類型。
      • 它會檢查 DispatcherHandlerDispatcherServlet、Servlet 等類的存在性,從而判斷應(yīng)用是 REACTIVE(響應(yīng)式)、SERVLET(標(biāo)準(zhǔn)的 Servlet Web 應(yīng)用)還是 NONE(非 Web 應(yīng)用)。我們最常見的 Spring MVC 應(yīng)用就是 SERVLET 類型。
  2. 執(zhí)行 setInitializers 方法:

    • 作用:設(shè)置應(yīng)用初始化器 (ApplicationContextInitializer)。
    • 最主要的部分是 getSpringFactoriesInstances(ApplicationContextInitializer.class) 方法:
      • 這個方法的作用是:使用 Spring 工廠加載機(jī)制,從 META-INF/spring.factories 配置文件中加載并實例化所有配置的 ApplicationContextInitializer 實現(xiàn)類。
      • 常見的初始化器如 ConfigurationWarningsApplicationContextInitializer(檢查配置警告)、ContextIdApplicationContextInitializer(設(shè)置上下文 ID)等。這些初始化器會在 ApplicationContext 刷新之前被調(diào)用。
  3. 執(zhí)行 setListeners 方法:

    • 作用:設(shè)置應(yīng)用監(jiān)聽器 (ApplicationListener)。
    • 最主要的部分同樣是 getSpringFactoriesInstances(ApplicationListener.class) 方法:
      • 這個方法的作用是:從 spring.factories 中加載并實例化所有配置的 ApplicationListener。
      • 這些監(jiān)聽器用于監(jiān)聽在應(yīng)用啟動過程中發(fā)布的各類事件,例如 ApplicationStartedEvent、ApplicationReadyEvent 等。ClearCachesApplicationListener(清除緩存)、FileEncodingApplicationListener(檢查文件編碼)都是常見的監(jiān)聽器。
  4. 執(zhí)行 deduceMainApplicationClass 方法:

    • 作用:推導(dǎo)出主應(yīng)用程序類(即我們寫了 main 方法的那個類)。
    • 原理是:遍歷當(dāng)前調(diào)用棧,找到第一個方法名為 main 的類。

至此,SpringApplication 對象構(gòu)造完畢,它已經(jīng)準(zhǔn)備好了初始化器和監(jiān)聽器。

第二階段:執(zhí)行run方法

執(zhí)行方法:SpringApplication.run(primarySources, args)

這是整個啟動流程最核心、最復(fù)雜的方法。

  1. 執(zhí)行 getRunListeners 方法并調(diào)用 listeners.starting()

    • 作用:獲取 SpringApplicationRunListeners 并發(fā)布 ApplicationStartingEvent 事件。
    • 說明:SpringApplicationRunListenersSpringApplicationRunListener 的集合,它專門用于監(jiān)聽 SpringApplicationrun 方法執(zhí)行過程中的關(guān)鍵節(jié)點。第一步就是發(fā)布應(yīng)用正在啟動的事件。
  2. 執(zhí)行 prepareEnvironment 方法:

    • 作用:準(zhǔn)備和應(yīng)用環(huán)境 (Environment),這是整個應(yīng)用配置的基礎(chǔ)。
    • 最主要的部分是:
      • getOrCreateEnvironment():根據(jù)應(yīng)用類型創(chuàng)建 StandardEnvironmentStandardServletEnvironment。
      • configureEnvironment(environment, args):配置環(huán)境,包括 PropertySources(屬性源,如 JVM 系統(tǒng)屬性、操作系統(tǒng)環(huán)境變量)和 Profiles(配置文件,如 “dev”, “prod”)。
      • listeners.environmentPrepared(environment):發(fā)布 ApplicationEnvironmentPreparedEvent 事件。這是一個極其重要的擴(kuò)展點,監(jiān)聽這個事件的監(jiān)聽器(最著名的是 ConfigFileApplicationListener)會從 application.propertiesapplication.yml 等文件中加載我們自定義的配置屬性。
  3. 執(zhí)行 printBanner 方法:

    • 作用:在控制臺打印 Spring Boot 的 Banner。
  4. 執(zhí)行 createApplicationContext 方法:

    • 作用:創(chuàng)建 ApplicationContext(IoC 容器)。
    • 根據(jù)第一步推斷出的 WebApplicationType,創(chuàng)建不同類型的上下文。對于 Servlet Web 應(yīng)用,會創(chuàng)建 AnnotationConfigServletWebServerApplicationContext。
  5. 執(zhí)行 prepareContext 方法:

    • 作用:準(zhǔn)備上面創(chuàng)建好的 ApplicationContext。
    • 最主要的部分是:
      • postProcessApplicationContext(context):后處理應(yīng)用上下文,例如設(shè)置 Bean 名稱生成器、資源加載器。
      • applyInitializers(context):應(yīng)用初始化器。調(diào)用在第一步中加載的所有 ApplicationContextInitializerinitialize 方法,允許我們在容器刷新前對上下文進(jìn)行自定義。
      • listeners.contextPrepared(context):發(fā)布 ApplicationContextInitializedEvent 事件,通知監(jiān)聽器上下文已準(zhǔn)備就緒。
      • load(context, sources.toArray(new Object[0])):將主源(即我們的 @SpringBootApplication 注解類)加載到上下文中,為后續(xù)的組件掃描和 Bean 定義注冊做準(zhǔn)備。
      • listeners.contextLoaded(context):發(fā)布 ApplicationPreparedEvent 事件,通知監(jiān)聽器上下文已加載完畢。

第三階段:刷新應(yīng)用上下文 (最最核心)

執(zhí)行方法:refreshContext(context)

這個方法內(nèi)部會調(diào)用 AbstractApplicationContext.refresh(),這是 Spring 框架容器初始化的標(biāo)準(zhǔn)流程。

  1. 執(zhí)行 prepareRefresh() 方法:

    • 作用:刷新前的準(zhǔn)備工作,例如初始化屬性源、驗證必要的屬性。
  2. 執(zhí)行 obtainFreshBeanFactory() 方法:

    • 作用:獲取或刷新內(nèi)部的 BeanFactoryDefaultListableBeanFactory)。BeanFactory 是 Spring 容器的基礎(chǔ)。
  3. 執(zhí)行 prepareBeanFactory(beanFactory) 方法:

    • 作用:準(zhǔn)備 BeanFactory,配置它的類加載器、后置處理器等標(biāo)準(zhǔn)配置。
  4. 執(zhí)行 postProcessBeanFactory(beanFactory) 方法:

    • 作用:允許在 Bean 定義加載完成后、實例化之前,對 BeanFactory 進(jìn)行后處理。這是一個空方法,供子類擴(kuò)展。
  5. 執(zhí)行 invokeBeanFactoryPostProcessors(beanFactory) 方法:

    • 作用:這是 Spring Boot 自動配置的魔法入口!
    • 最主要的部分是:調(diào)用所有 BeanFactoryPostProcessor。
    • 其中,ConfigurationClassPostProcessor 會解析 @Configuration 注解的類。它會發(fā)現(xiàn)我們的主類上的 @SpringBootApplication 注解。
    • @SpringBootApplication 中包含 @EnableAutoConfiguration,后者會導(dǎo)入 AutoConfigurationImportSelector。
    • AutoConfigurationImportSelector 會從 META-INF/spring.factories 中加載所有 EnableAutoConfiguration 鍵對應(yīng)的自動配置類(如 DataSourceAutoConfiguration, WebMvcAutoConfiguration)。
    • 這些自動配置類根據(jù)條件(如類路徑下是否存在某個類、是否設(shè)置了某個屬性等)決定是否生效,并向容器中批量添加 Bean 定義。
  6. 執(zhí)行 registerBeanPostProcessors(beanFactory) 方法:

    • 作用:注冊 BeanPostProcessor。這些處理器會在 Bean 實例化之后、初始化前后 被調(diào)用,用于對 Bean 進(jìn)行增強(qiáng)(如 @Autowired, @PostConstruct 等功能都是通過 BeanPostProcessor 實現(xiàn)的)。
  7. 執(zhí)行 initMessageSource() 方法:

    • 作用:初始化國際化相關(guān)的消息源。
  8. 執(zhí)行 initApplicationEventMulticaster() 方法:

    • 作用:初始化應(yīng)用事件廣播器,用于事件發(fā)布。
  9. 執(zhí)行 onRefresh() 方法:

    • 作用:這是 Spring Boot 創(chuàng)建并啟動內(nèi)嵌 Web 服務(wù)器的關(guān)鍵步驟!
    • ServletWebServerApplicationContext 中,此方法被重寫。
    • 最主要的部分是 createWebServer() 方法:
      • 這個方法的作用是:從 BeanFactory 中獲取 ServletWebServerFactory(如 TomcatServletWebServerFactory)。
      • 調(diào)用 factory.getWebServer(...) 方法,這會創(chuàng)建內(nèi)嵌的 Tomcat/Jetty/Undertow 服務(wù)器實例,并初始化 Servlet 容器(初始化 DispatcherServlet 并注冊到容器中)。此時,Web 服務(wù)器已經(jīng)創(chuàng)建好,但尚未開始監(jiān)聽端口。
  10. 執(zhí)行 registerListeners() 方法:

    • 作用:注冊監(jiān)聽器,將事件監(jiān)聽器注冊到第 8 步初始化的事件廣播器中。
  11. 執(zhí)行 finishBeanFactoryInitialization(beanFactory) 方法:

    • 作用:完成 BeanFactory 的初始化,實例化所有剩余的非懶加載單例 Bean。
    • 這是 IoC 容器依賴注入發(fā)生的主要階段。我們的 Controller、Service、Repository 等組件都在這個階段被創(chuàng)建和裝配。
  12. 執(zhí)行 finishRefresh() 方法:

    • 作用:完成上下文的刷新工作,發(fā)布最終事件。
    • 最主要的部分是:
      • publishEvent(new ContextRefreshedEvent(this)):發(fā)布 ContextRefreshedEvent 事件。
      • ServletWebServerApplicationContext 中,還會調(diào)用 finishRefresh() 的一個擴(kuò)展,最終啟動內(nèi)嵌的 Web 服務(wù)器(例如 TomcatWebServer.start()),開始監(jiān)聽指定的端口。至此,我們的應(yīng)用已經(jīng)可以處理 HTTP 請求了。

第四階段:啟動后處理

  • 執(zhí)行 afterRefresh(context, applicationArguments) 方法:
    • 作用:刷新后處理,默認(rèn)為空。是一個擴(kuò)展點。
  • 執(zhí)行 listeners.started(context) 方法:
    • 作用:發(fā)布 ApplicationStartedEvent 事件,通知所有監(jiān)聽器應(yīng)用已啟動。
  • 執(zhí)行 callRunners(applicationArguments) 方法:
    • 作用:調(diào)用 ApplicationRunnerCommandLineRunner 接口的實現(xiàn)類。
    • 這是開發(fā)者可以在應(yīng)用啟動后、開始接收流量前,執(zhí)行一些特定初始化邏輯的常用方式。
  • 執(zhí)行 listeners.ready(context, timeTaken) 方法:
    • 作用:發(fā)布 ApplicationReadyEvent 事件。這個事件標(biāo)志著應(yīng)用已完全啟動完畢,處于就緒狀態(tài)。它與 ApplicationStartedEvent 的區(qū)別在于,此時所有 Bean 都已初始化,內(nèi)嵌服務(wù)器已在運行。
    • 返回 ApplicationContext
    • 作用:將已經(jīng)完全初始化好的 ApplicationContext 返回。

總結(jié)

整個流程從 main 方法開始,經(jīng)歷了 環(huán)境準(zhǔn)備 -> 容器創(chuàng)建 -> Bean定義加載(自動配置) -> Bean實例化(依賴注入) -> 內(nèi)嵌服務(wù)器啟動 -> 運行自定義初始化邏輯 等一系列復(fù)雜而精密的步驟,最終將一個功能完備的 Spring Boot 應(yīng)用呈現(xiàn)在我們面前。其中 refreshContext() 是整個流程的心臟,而自動配置和內(nèi)嵌服務(wù)器是 Spring Boot 兩大核心特性的實現(xiàn)關(guān)鍵。

到此這篇關(guān)于Spring Boot 應(yīng)用程序啟動時執(zhí)行流程的文章就介紹到這了,更多相關(guān)Spring Boot 啟動時執(zhí)行流程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何簡單使用mybatis注解

    如何簡單使用mybatis注解

    之前我們介紹了使用JDBC或者java框架mabatis來實現(xiàn)對數(shù)據(jù)庫的操作,現(xiàn)在為了簡化代碼,提高程序的簡潔性,我們探索如何使用注解進(jìn)行開發(fā),需要的朋友可以參考下
    2021-06-06
  • java實現(xiàn)多線程之定時器任務(wù)

    java實現(xiàn)多線程之定時器任務(wù)

    本篇文章主要介紹了java實現(xiàn)多線程之定時器任務(wù),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • Java中回調(diào)函數(shù)?(callback)?及其實際應(yīng)用場景

    Java中回調(diào)函數(shù)?(callback)?及其實際應(yīng)用場景

    在Java中回調(diào)函數(shù)(Callback)是一種常見的設(shè)計模式,用于實現(xiàn)異步操作或事件處理,這篇文章主要給大家介紹了關(guān)于Java中回調(diào)函數(shù)?(callback)?及其實際應(yīng)用場景的相關(guān)資料,需要的朋友可以參考下
    2024-02-02
  • Gradle在國內(nèi)配置鏡像加速的實現(xiàn)步驟

    Gradle在國內(nèi)配置鏡像加速的實現(xiàn)步驟

    在國內(nèi)使用 Gradle 構(gòu)建項目時,最大的痛點就是 依賴下載賊慢,甚至卡死,下面教你如何 配置國內(nèi)鏡像加速 Gradle 下載依賴,主要是通過改寫 repositories 中的源地址來實現(xiàn),親測有效,需要的朋友可以參考下
    2025-05-05
  • kafka消費不到數(shù)據(jù)的排查過程

    kafka消費不到數(shù)據(jù)的排查過程

    這篇文章主要介紹了kafka消費不到數(shù)據(jù)的排查過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • springboot打包如何忽略Test單元測試

    springboot打包如何忽略Test單元測試

    這篇文章主要介紹了springboot打包如何忽略Test單元測試,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 帶你快速搞定java多線程(3)

    帶你快速搞定java多線程(3)

    這篇文章主要介紹了java多線程編程實例,分享了幾則多線程的實例代碼,具有一定參考價值,加深多線程編程的理解還是很有幫助的,需要的朋友可以參考下
    2021-07-07
  • Java基礎(chǔ)之讓你徹底搞懂代理模式

    Java基礎(chǔ)之讓你徹底搞懂代理模式

    這篇文章主要介紹了Java基礎(chǔ)之讓你徹底搞懂代理模式,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • SpringBoot集成Devtools實現(xiàn)熱更新

    SpringBoot集成Devtools實現(xiàn)熱更新

    DevTools是開發(fā)者工具集,主要用于簡化開發(fā)過程中的熱部署問題,熱部署是指在開發(fā)過程中,當(dāng)代碼發(fā)生變化時,無需手動重啟應(yīng)用,系統(tǒng)能夠自動檢測并重新加載修改后的代碼,本文給大家介紹了SpringBoot集成Devtools實現(xiàn)熱更新,需要的朋友可以參考下
    2024-08-08
  • 使用WebUploader實現(xiàn)上傳文件功能(一)

    使用WebUploader實現(xiàn)上傳文件功能(一)

    這篇文章主要為大家詳細(xì)介紹了使用WebUploader實現(xiàn)上傳文件功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01

最新評論

马鞍山市| 巨野县| 梨树县| 绍兴县| 景德镇市| 西丰县| 朔州市| 土默特右旗| 长治市| 盘山县| 百色市| 福鼎市| 南皮县| 中山市| 灯塔市| 万山特区| 繁昌县| 达拉特旗| 沙坪坝区| 依兰县| 益阳市| 依安县| 体育| 灵武市| 舟山市| 页游| 汝州市| 绵阳市| 曲水县| 尼勒克县| 乌恰县| 和政县| 个旧市| 色达县| 蓝田县| 湛江市| 柞水县| 炎陵县| 永修县| 湘西| 思南县|