Spring源碼解析 - SpringApplication 屬性-初始化initializers, listeners -Spring提供的鉤子函數

初始化源碼

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {~~~setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));~~~
}private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {// 獲取當前 SpringApplication 實例的類加載器// 這個類加載器將用于加載類和資源ClassLoader classLoader = getClassLoader();// 從 META-INF/spring.factories 文件中加載指定類型的工廠類名稱// 使用 LinkedHashSet 保證加載的類名稱的順序,并且去除重復項// SpringFactoriesLoader.loadFactoryNames(type, classLoader) 會讀取 spring.factories 文件中指定類型的類名稱Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));// 根據加載的類名稱,反射創建指定類型的實例// createSpringFactoriesInstances 方法會根據類名稱和構造函數參數類型及參數值,反射創建實例List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);// 根據 @Order 注解或實現 Ordered 接口的順序對實例進行排序// AnnotationAwareOrderComparator.sort(instances) 會根據 @Order 注解或 Ordered 接口的值對實例進行排序AnnotationAwareOrderComparator.sort(instances);// 返回創建并排序后的實例集合return instances;
}

SpringApplication中 initializers 鉤子實現

1. 實現 ApplicationContextInitializer 接口

你需要創建一個類,實現 ApplicationContextInitializer 接口,并在 initialize 方法中實現自定義的初始化邏輯。

public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {// 在這里執行自定義邏輯System.out.println("Executing custom logic before Spring context refresh");// 例如,設置環境變量ConfigurableEnvironment environment = applicationContext.getEnvironment();environment.setProperty("custom.property", "customValue");}
}
2. 注冊初始化器

你可以在 SpringApplication 的構造方法中顯式注冊這些初始化器,或者通過 META-INF/spring.factories 文件自動發現它們。

顯式注冊

SpringApplication 的構造方法中顯式注冊初始化器:

public class MyApplication {public static void main(String[] args) {SpringApplication application = new SpringApplication(MyApplication.class);// 顯式注冊初始化器application.addInitializers(new MyApplicationContextInitializer());application.run(args);}
}
通過 META-INF/spring.factories 文件自動發現

resources 目錄下創建或編輯 META-INF/spring.factories 文件,并添加你的初始化器類:

org.springframework.context.ApplicationContextInitializer=\
com.example.MyApplicationContextInitializer

初始化器的執行順序

  • ApplicationContextInitializer:在 Spring 容器刷新之前執行。
  • ApplicationRunnerCommandLineRunner:在 Spring 容器刷新之后執行。
    ApplicationListener 是 Spring 提供的一個接口,用于監聽 Spring 應用上下文中的事件。通過實現 ApplicationListener 接口,你可以捕獲并處理特定的事件,從而在 Spring 應用的生命周期中執行自定義邏輯。

以下是使用 ApplicationListener 鉤子的步驟和示例代碼:


SpringApplication中listeners 鉤子實現

ApplicationListener接口繼承自Java的EventListener接口,表示一個事件監聽器,它能夠接收并處理特定類型的事件。在Spring中,當一個事件被發布時(通常是通過ApplicationContext的publishEvent方法),Spring會查找所有實現了ApplicationListener接口并且聲明了要監聽的事件類型的Bean,然后調用這些Bean的onApplicationEvent方法來處理事件。

1. 實現 ApplicationListener 接口

你需要創建一個類,實現 ApplicationListener 接口,并重寫 onApplicationEvent 方法。onApplicationEvent 方法會在事件發生時被調用。

示例代碼
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class MyApplicationListener implements ApplicationListener<ApplicationReadyEvent> {@Overridepublic void onApplicationEvent(ApplicationReadyEvent event) {// 在這里執行自定義邏輯System.out.println("Application is ready and fully started!");// 你可以在這里執行一些初始化邏輯或檢查}
}

2. 監聽特定事件

Spring 提供了多種事件類型,例如:

  • ContextRefreshedEvent:在 Spring 容器刷新時觸發。
  • ApplicationReadyEvent:在 Spring 應用完全啟動后觸發。
  • ContextStartedEvent:在 Spring 容器啟動時觸發。
  • ContextStoppedEvent:在 Spring 容器停止時觸發。
  • ContextClosedEvent:在 Spring 容器關閉時觸發。

你可以選擇監聽特定的事件類型。例如,如果你想在應用啟動后執行一些邏輯,可以監聽 ApplicationReadyEvent

3. 自定義事件

你還可以定義自己的事件類型,并在需要的時候發布這些事件。

定義自定義事件
import org.springframework.context.ApplicationEvent;public class MyCustomEvent extends ApplicationEvent {private String message;public MyCustomEvent(Object source, String message) {super(source);this.message = message;}public String getMessage() {return message;}
}
發布自定義事件
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;@Service
public class MyService {@Autowiredprivate ApplicationEventPublisher eventPublisher;public void doSomething() {// 執行一些業務邏輯System.out.println("Doing something...");// 發布自定義事件MyCustomEvent customEvent = new MyCustomEvent(this, "Custom event message");eventPublisher.publishEvent(customEvent);}
}
監聽自定義事件
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class MyCustomEventListener implements ApplicationListener<MyCustomEvent> {@Overridepublic void onApplicationEvent(MyCustomEvent event) {// 在這里處理自定義事件System.out.println("Received custom event: " + event.getMessage());}
}

4. 使用注解方式監聽事件

除了實現 ApplicationListener 接口,你還可以使用 @EventListener 注解來監聽事件。

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

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

相關文章

簡單聊聊PowerShell

1、powershell和cmdpowershell簡單來說也是一個控制終端&#xff0c;他也經常拿出來和windows自帶的CMD來進行對比。windows系統一般來說這兩者都是自帶的。雖然cmd平時大家用的最多&#xff0c;但他是非常古老的&#xff0c;可以用來執行簡單的批處理文件&#xff0c;如.bat等…

Spring系列之Spring AI入門

概述 GitHub&#xff0c;官網&#xff0c;目前最新版是1.0.1。 功能&#xff1a; 跨AI提供商的可移植API&#xff1a;用于聊天、文本到圖像和嵌入模型。支持同步和流API選項。還支持下拉訪問模型特定功能。跨Vector Store提供商的可移植API&#xff0c;包括同樣可移植的新穎…

ELK常見的問題

ELK 棧在使用過程中會遇到各種問題&#xff0c;以下是常見問題分類及解決方案&#xff0c;涵蓋 ?Elasticsearch、Logstash、Kibana 和 Beats&#xff08;如 Filebeat&#xff09;?? 四大組件&#xff1a; &#x1f6a8; ?一、連接與通信問題? 1. ?Elasticsearch 拒絕連接…

物理AI與人形機器人:從實驗室到產業化的關鍵跨越

2025年8月9日&#xff0c;北京——世界機器人大會&#xff08;WRC&#xff09;的開幕成為物理AI與機器人技術發展的集中展示場。英偉達在大會預告中首次提出“物理AI將重塑50萬億美元市場”的論斷&#xff0c;涵蓋工業制造、醫療、低空經濟等領域。與此同時&#xff0c;宇樹科技…

使用 Vuepress + GitHub Pages 搭建項目文檔(2)- 使用 GitHub Actions 工作流自動部署

在上一篇文章中&#xff0c;我們已經成功用 VuePress 搭建了項目文檔&#xff0c;并使用 sh 腳本部署到了 GitHub Pages。 但隨著文檔的更新頻率增加&#xff0c;每次都要手動推送&#xff0c;那有沒有不需要手動推送的方法呢&#xff1f;那必須有。 這次我們將用 GitHub Actio…

Python爬蟲實戰:研究PSpider框架,構建電商數據采集和分析系統

一、引言 1.1 研究背景 在大數據時代,數據已成為驅動科技創新、商業決策和社會發展的核心資源。據 IDC 預測,全球數據量將從 2020 年的 64ZB 增長至 2025 年的 175ZB,其中互聯網公開數據占比超過 60%。如何從海量網絡信息中高效、精準地提取有價值的數據,成為學術界和工業…

劍指offer第2版:動態規劃+記憶化搜索

前三題是同一種模型&#xff0c;所以我分別用遞推、記憶化、動歸來做 一、p74-JZ10 斐波那契數列 斐波那契數列_牛客題霸_牛客網 class Solution { public:int Fibonacci(int n) {// write code hereif(n1||n2) return 1;int a1,b1,c1;while(n>2){cab;ab;bc;--n;}return c…

Unity 調節 Rigidbody2D 響應速度的解決方案【資料】

可以通過多種方式調節 Unity 中 Rigidbody2D 的響應速度&#xff0c;包括降低物理更新頻率、屏蔽過小值以及優化物理參數。以下是幾種有效的實現方法&#xff1a;1. 降低物理更新頻率&#xff08;不推薦直接修改&#xff09;雖然可以修改 Time.fixedDeltaTime 來降低物理更新頻…

力扣-189.輪轉數組

題目鏈接 189.輪轉數組 class Solution {public void reverse(int[] nums, int i, int j) {while (i < j && i > 0 && j < nums.length) {int temp nums[i];nums[i] nums[j];nums[j] temp;i;j--;}}public void rotate(int[] nums, int k) {k k …

Linux命令行安裝Climate Data Operators(CDO)的方法

本文介紹在Linux操作系統的發行版本Ubuntu中&#xff0c;基于命令行&#xff0c;配置Climate Data Operators&#xff08;CDO&#xff09;這個用于操作、分析氣候及其他相關數據的命令行工具的方法。 最近&#xff0c;需要對一批.nc格式文件加以處理&#xff1b;在之前&#xf…

如何為您的服務器選擇正確的 PHP 版本

PHP作為最流行的服務器端腳本語言之一&#xff0c;持續演進并定期發布新版本。為您的服務器選擇正確的PHP版本對于網站性能、安全性和功能兼容性至關重要。本文將指導您如何做出明智的選擇。了解PHP版本的生命周期在選擇PHP版本前&#xff0c;首先需要了解PHP的版本支持政策&am…

從0開始的中后臺管理系統-5(userList動態展示以及上傳圖片和彈出創建用戶表單)

項目用的都是antd組件&#xff0c;這里的userList組件展示的表單組件的數據直接get請求拿過來展示的&#xff0c;這里隨機生成了50個用戶只是為了展示表單的api設置。首先就是表單展示需要兩個參數current和pageSize兩個屬性控制表單的最大分頁和當前頁面。那么我們就設置初始值…

Spring MVC REST API設計詳解:從零構建高效接口

1. Spring MVC與REST API基礎1.1 RESTful架構的六大約束詳解RESTful架構是Roy Thomas Fielding在2000年博士論文中提出的軟件架構風格&#xff0c;它包含六個核心約束&#xff0c;這些約束共同構成了RESTful API的設計原則。客戶端-服務器約束&#xff08;Client-Server&#x…

基于STM32F030C8T6單片機實現與CH224Q誘騙芯片的I2C通信和電壓輸出配置

基于項目的需要,對STM32F030的IIC研究了幾天,終于完成了通信,接下來具體實現如下: 本單片機使用的是PB8和PB9管腳進行實現,采用的是模擬的IIC進行 void MyI2C_W_SCL(uint8_t BitValue)//這三個函數將讀寫io口封裝起來,增強可讀性 { GPIO_WriteBit(GPIOB, GPIO_Pin_8…

TSMaster-C小程序使用

打開同星的TSMaster&#xff0c;推薦用32版本的&#xff0c;比64更穩定。同星的TSMaster的C小程序支持用戶嵌入代碼來控制CAN報文的收發邏輯。便于開發。點擊設計里面的C小程序。 比如我現在想用小程序來實現繼電器0先開后關開1s關1s&#xff0c;然后繼電器1開1s關1s…如此往復…

XSS滲透測試原理/步驟/攻擊方法/防御/常用語法

**核心概念回顧&#xff1a;**XSS漏洞一直被評估為web漏洞中危害較大的漏洞&#xff0c;在OWASP TOP10的排名中一直屬于前三的江湖地位。XSS是一種發生在前端瀏覽器端的漏洞&#xff0c;所以其危害的對象也是前端用戶。 形成XSS漏洞的主要原因是程序對輸入和輸出沒有做合適的處…

目標檢測數據集 - 自動駕駛場景道路異常檢測數據集下載「包含VOC、COCO、YOLO三種格式」

數據集介紹&#xff1a;自動駕駛場景道路異常檢測數據集&#xff0c;真實場景高質量道路圖片數據&#xff0c;涉及場景豐富&#xff0c;且類別豐富&#xff0c;劃分為 "LMVs 輕型機動車&#xff08;汽車、摩托車、小型卡車、小型貨車"、"HMVs 公交車、卡車、拖拉…

多模態新方向|從數據融合到場景落地,解鎖視覺感知新范式

來gongzhonghao【圖靈學術計算機論文輔導】&#xff0c;快速拿捏更多計算機SCI/CCF發文資訊&#xff5e;多模態學習&#xff08;Multimodal Learning&#xff09;是通過整合多種數據模態來提升模型對復雜場景感知與理解能力的技術&#xff0c;其核心是利用不同模態的互補性突破…

機器學習之隨機森林

目錄 一、什么是隨機森林&#xff1f; 1. 從決策樹到集成學習&#xff1a;為什么需要 "森林"&#xff1f; 2.什么是集成學習 二、隨機森林的工作原理 三、隨機森林構造過程 四、隨機森林api介紹 五、隨機森林的優缺點 六、垃圾郵件判斷案例 1.數據集介紹 ?…

云平臺運維工具 —— 阿里云原生工具

一、簡介阿里云作為國內領先的云服務提供商&#xff0c;擁有一套完整的原生運維工具體系&#xff0c;這些工具與阿里云的各類服務深度融合&#xff0c;能夠滿足用戶在資源部署、監控告警、權限管理、自動化運維等方面的需求。無論是簡單的應用托管還是復雜的企業級架構&#xf…