【Spring Boot 源碼學習】BootstrapRegistry 初始化器實現

《Spring Boot 源碼學習系列》

在這里插入圖片描述

BootstrapRegistry 初始化器實現

  • 一、引言
  • 二、往期內容
  • 三、主要內容
    • 3.1 BootstrapRegistry
    • 3.2 BootstrapRegistryInitializer
    • 3.3 BootstrapRegistry 初始化器實現
      • 3.3.1 定義 DemoBootstrapper
      • 3.3.2 添加 DemoBootstrapper
  • 四、總結

一、引言

前面的博文《BootstrapRegistryInitializer 詳解》,Huazie 帶大家一起詳細分析了 Spring Boot 啟動時加載并初始化 BootstrapRegistryInitializer 及其相關的類的邏輯。本篇就讓我們自定義 BootstrapRegistryInitializer 接口實現,以此來執行自定義的初始化操作【如注冊自定義的 Bean、添加 BootstrapContext 關閉監聽器】。

在這里插入圖片描述

二、往期內容

在開始本篇的內容介紹之前,我們先來看看往期的系列文章【有需要的朋友,歡迎關注系列專欄】:

Spring Boot 源碼學習
Spring Boot 項目介紹
Spring Boot 核心運行原理介紹
【Spring Boot 源碼學習】@EnableAutoConfiguration 注解
【Spring Boot 源碼學習】@SpringBootApplication 注解
【Spring Boot 源碼學習】走近 AutoConfigurationImportSelector
【Spring Boot 源碼學習】自動裝配流程源碼解析(上)
【Spring Boot 源碼學習】自動裝配流程源碼解析(下)
【Spring Boot 源碼學習】深入 FilteringSpringBootCondition
【Spring Boot 源碼學習】OnClassCondition 詳解
【Spring Boot 源碼學習】OnBeanCondition 詳解
【Spring Boot 源碼學習】OnWebApplicationCondition 詳解
【Spring Boot 源碼學習】@Conditional 條件注解
【Spring Boot 源碼學習】HttpEncodingAutoConfiguration 詳解
【Spring Boot 源碼學習】RedisAutoConfiguration 詳解
【Spring Boot 源碼學習】JedisConnectionConfiguration 詳解
【Spring Boot 源碼學習】初識 SpringApplication
【Spring Boot 源碼學習】Banner 信息打印流程
【Spring Boot 源碼學習】自定義 Banner 信息打印
【Spring Boot 源碼學習】BootstrapRegistryInitializer 詳解
【Spring Boot 源碼學習】ApplicationContextInitializer 詳解
【Spring Boot 源碼學習】ApplicationListener 詳解
【Spring Boot 源碼學習】SpringApplication 的定制化介紹
【Spring Boot 源碼學習】BootstrapRegistry 詳解
【Spring Boot 源碼學習】深入 BootstrapContext 及其默認實現

三、主要內容

注意: 以下涉及 Spring Boot 源碼 均來自版本 2.7.9,其他版本有所出入,可自行查看源碼。

3.1 BootstrapRegistry

在《BootstrapRegistry 詳解》 中,Huazie 詳細介紹了 BootstrapRegistry 的源碼,這有助于下面介紹的 BootstrapRegistry 初始化器的實現邏輯,有不知道的朋友們直接查看即可,這里不再贅述。

3.2 BootstrapRegistryInitializer

在《BootstrapRegistryInitializer 詳解》 中,Huazie 詳解分析了加載并初始化 BootstrapRegistryInitializer 的邏輯,這同樣有助于
理解下面將要講解的內容,還不熟悉的朋友們趕緊花點時間了解下,這里不再贅述。

3.3 BootstrapRegistry 初始化器實現

3.3.1 定義 DemoBootstrapper

下面我們來定義一個類 DemoBootstrapper,該類實現 BootstrapRegistryInitializer 接口,如下:

public class DemoBootstrapper implements BootstrapRegistryInitializer {@Overridepublic void initialize(BootstrapRegistry registry) {// 注冊一些自定義的對象 或者 加載自定義的一些配置}
}

在《BootstrapRegistryInitializer 詳解》 的 3.2 小節,Huazie 介紹了 BootstrapRegistryInitializer 的加載過程,上述我們自定義的 DemoBootstrapper 也會在 Spring Boot 啟動引導階段進行加載并初始化。

上述定義中,我們只是展示了一個空實現的類,其中的 initialize 方法還未做處理。

至于 initialize 方法中該添加哪些邏輯,這就要看它的參數 BootstrapRegistry 接口了。

下面代碼,Huazie 演示了如何 注冊自定義的對象,以及添加 引導上下文關閉事件監聽器

// 注冊 User對象,它就是一個簡單的 POJO 類,含兩個成員變量:名稱 name 和年齡 age
registry.register(User.class, context -> new User("Huazie", 18));
// 添加 BootstrapContext關閉 監聽器
registry.addCloseListener(new DemoBootstrapContextClosedListener());

DemoBootstrapContextClosedListener ,即引導上下文關閉事件監聽器,相關演示代碼如下:

public class DemoBootstrapContextClosedListener implements ApplicationListener<BootstrapContextClosedEvent>, Ordered {@Overridepublic void onApplicationEvent(BootstrapContextClosedEvent event) {BootstrapContext bootstrapContext = event.getBootstrapContext();if (bootstrapContext.isRegistered(User.class)) {System.out.println("BootstrapContext關閉時獲取User:" + bootstrapContext.get(User.class));}}@Overridepublic int getOrder() {return 1;}
}

雖然上面添加了引導上下文關閉事件監聽器,但是我們還不知道什么時候它會被執行。

DemoBootstrapContextClosedListener 中,我們看到了 BootstrapContext 的使用,顯然這里涉及到了引導上下文的實際使用場景,由于篇幅受限,將在下篇介紹,大家不妨期待一下。

另外,在 DemoBootstrapContextClosedListener 中,還看到它實現了 Ordered 接口【spring-core 包中的接口】。

那么在事件監聽器中,這個 Ordered 接口是用來做什么的呢?

在回答這個問題之前,我們先來看看 Ordered 接口的源碼:

public interface Ordered {int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;int LOWEST_PRECEDENCE = Integer.MAX_VALUE;int getOrder();
}

Ordered 接口定義了兩個常量和一個方法:

  • HIGHEST_PRECEDENCE:最高優先級值的有用常數【最小的 Integer 值】
  • LOWEST_PRECEDENCE :最低優先級值的有用常數【最大的 Integer 值】
  • int getOrder() :獲取當前對象的優先級值【值越小,優先級越高】

源碼中對于 Ordered 接口是這樣說的:

它可以被需要排序的對象實現,例如在集合中。實際的排序可以被解讀為優先級排序,其中第一個對象(即有著最低的排序值)具有最高的優先級。

當然,Ordered 接口還有一個擴展接口,即優先級標記接口 PriorityOrderedPriorityOrdered 對象總是優先于普通 Ordered 對象,無論它們的排序值如何。當對一組 Ordered 對象進行排序時,PriorityOrdered 對象和普通 Ordered 對象實際上被視為兩個獨立的子集,PriorityOrdered 對象子集先于普通 Ordered 對象子集,并在這些子集內部應用相對排序。

上述排序邏輯請查看 spring-core 包中的 AnnotationAwareOrderComparator 類 和 OrderComparator 類,這里不再贅述了。

現在可以回答上面的問題了:在事件監聽器中實現 Ordered 接口,可以用來確保 多個監聽同一事件的監聽器 可以按照我們 預定的順序執行

3.3.2 添加 DemoBootstrapper

不過,要想能夠加載到自定義的 DemoBootstrapper ,我們還需要將它添加到 bootstrapRegistryInitializers 中才可以。

// SpringApplication的私有變量
private List<BootstrapRegistryInitializer> bootstrapRegistryInitializers;

那么,我們該如何添加呢?

通過閱讀 SpringApplication 的源碼,可以總結如下的兩種方式:

  • META-INF/spring.factories 中添加 org.springframework.boot.BootstrapRegistryInitializer 的配置。這種方式,我們從 《BootstrapRegistryInitializer 詳解》 的 3.2 小節可見一斑。

    org.springframework.boot.BootstrapRegistryInitializer=com.example.demo.DemoBootstrapper
    
  • 通過 SpringApplication 中的 addBootstrapRegistryInitializer 方法添加。其實這里在筆者的《SpringApplication 的定制化介紹》中的 1.5 小節也提及過。

    SpringApplication springApplication = new SpringApplication(DemoApplication.class);
    springApplication.addBootstrapRegistryInitializer(new DemoBootstrapper());
    // 其他省略。。。
    

四、總結

本篇 Huazie 介紹了如何自定義 BootstrapRegistry 初始化器實現,其中演示如何在引導上下文中注冊了自定義的對象以及如何在引導上下文中添加引導上下文關閉事件監聽器

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

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

相關文章

Avalonia學習(二十八)-OpenGL

Avalonia已經繼承了opengl&#xff0c;詳細的大家可以自己查閱。Avalonia里面啟用opengl繼承OpenGlControlBase類就可以了。有三個方法。分別是初始化、繪制、釋放。 這里把官方源碼的例子扒出來給大家看一下。源碼在我以前發布的單組件里面。地址在前面的界面總結博文里面。 …

圖數據庫 之 Neo4j - 應用場景4 - 反洗錢(9)

原理 Neo4j圖數據庫可以用于構建和分析數據之間的關系。它使用節點和關系來表示數據,并提供實時查詢能力。通過使用Neo4j,可以將大量的交易數據導入圖數據庫,并通過查詢和分析圖結構來發現洗錢行為中的模式和關聯。 案例分析 假設有一家轉賬服務公司,有以下交易數據,每個…

YOLOv9有效改進|使用空間和通道重建卷積SCConv改進RepNCSPELAN4

專欄介紹&#xff1a;YOLOv9改進系列 | 包含深度學習最新創新&#xff0c;主力高效漲點&#xff01;&#xff01;&#xff01; 一、改進點介紹 SCConv是一種即插即用的空間和通道重建卷積。 RepNCSPELAN4是YOLOv9中的特征提取模塊&#xff0c;類似YOLOv5和v8中的C2f與C3模塊。 …

突破編程_C++_設計模式(建造者模式)

1 建造者模式的概念 建造者模式&#xff08;Builder Pattern&#xff09;是一種創建型設計模式&#xff0c;也被稱為生成器模式。它的核心思想是將一個復雜對象的構建與它的表示分離&#xff0c;使得同樣的構建過程可以創建不同的表示。 在建造者模式中&#xff0c;通常包括以…

MySQL進階:MySQL事務、并發事務問題及隔離級別

&#x1f468;?&#x1f393;作者簡介&#xff1a;一位大四、研0學生&#xff0c;正在努力準備大四暑假的實習、 &#x1f30c;上期文章&#xff1a;MySQL進階&#xff1a;視圖&&存儲過程&&存儲函數&&觸發器 &#x1f4da;訂閱專欄&#xff1a;MySQL進…

Docker Machine windows系統下 安裝

如果你是 Windows 平臺&#xff0c;可以使用 Git BASH&#xff0c;并輸入以下命令&#xff1a; basehttps://github.com/docker/machine/releases/download/v0.16.0 &&mkdir -p "$HOME/bin" &&curl -L $base/docker-machine-Windows-x86_64.exe >…

點燃技能火花:探索PyTorch學習網站,開啟AI編程之旅!

介紹&#xff1a;PyTorch是一個開源的Python機器學習庫&#xff0c;它基于Torch&#xff0c;專為深度學習和科學計算而設計&#xff0c;特別適合于自然語言處理等應用程序。以下是對PyTorch的詳細介紹&#xff1a; 歷史背景&#xff1a;PyTorch起源于Torch&#xff0c;一個用于…

【真機Bug】異步加載資源未完成訪問單例導致資源創建失敗

1.錯誤表現描述 抽卡時&#xff0c;10抽展示界面為A。抽取內容可能是整卡或者碎片&#xff0c;抽到整卡&#xff0c;會有立繪展示和點擊詳情的按鈕。點擊詳情后出現詳情頁B。【此時界面A預制體被銷毀&#xff0c;卡片數據進入數據緩存池】點擊頁面B的返回按鈕&#xff0c;單例…

C++——模版

前言&#xff1a;哈嘍小伙伴們好久不見&#xff0c;這是2024年的第一篇博文&#xff0c;我們將繼續C的學習&#xff0c;今天這篇文章&#xff0c;我們來習一下——模版。 目錄 一.什么是模版 二.模版分類 1.函數模版 2.類模板 總結 一.什么是模版 說起模版&#xff0c;我們…

線索二叉樹

線索二叉樹即從前、中、后序三種遍歷中其中一種來看&#xff0c;樹中的左右孩子都不會是空著的&#xff0c;都會指向對應的前驅和后驅。 以中序遍歷為例&#xff0c;二叉樹線索化過程如下&#xff1a; 先是樹的結構 typedef struct ThreadNode{Elemetype data;struct ThreadNo…

微服務面試題之套路一

面試題 一、你的項目是從SpringBoot演進到微服務架構的&#xff0c;你在此過程中有調研過哪些技術&#xff0c;怎么調研落地的? 微服務通信框架&#xff1a; 需要選擇適合項目的微服務通信框架&#xff0c;如Dubbo、Spring Cloud或gRPC Feign RestTemplate 等。調研方式可以是…

高性能通信之Netty

一, 同步IO(BIO)模型的架構 一般針對性能不高的情況下可以使用. 二,異步IO(NIO)模型的架構 多路復用(epoll模型):

【LeetCode:124. 二叉樹中的最大路徑和 + 二叉樹+遞歸】

&#x1f680; 算法題 &#x1f680; &#x1f332; 算法刷題專欄 | 面試必備算法 | 面試高頻算法 &#x1f340; &#x1f332; 越難的東西,越要努力堅持&#xff0c;因為它具有很高的價值&#xff0c;算法就是這樣? &#x1f332; 作者簡介&#xff1a;碩風和煒&#xff0c;…

前端開發人員如何做好SEO

前端開發人員如何做好SEO SEO工作不僅限于專業人員。前端開發者也可以在日常開發中實施一些代碼層面的SEO優化。 以下是一些前端常用的SEO方法&#xff1a; 設置合理的title、keywords、description title、keywords、description對SEO至關重要&#xff0c;需貼合頁面內容編…

Codeforces Round 931 (Div. 2) (A~B)

比賽&#xff1a;Codeforces Round 931 (Div. 2) (A~B) 目錄&#xff1a;A B A題&#xff1a;Too Min Too Max 標簽: 構造算法&#xff08;constructive algorithms&#xff09;貪心&#xff08;greedy&#xff09;數學&#xff08;math&#xff09; 題目大意 對數組 a 找到…

【力扣hot100】刷題筆記Day19

前言 回溯回溯回溯&#xff01;早上整理檔案竟然用了桶排序&#xff0c;不愧是算法狂魔們 79. 單詞搜索 - 力扣&#xff08;LeetCode&#xff09; DFS class Solution:def exist(self, board: List[List[str]], word: str) -> bool:m, n len(board), len(board[0])# used…

mysql timestamp轉換為datetime

MySQL timestamp轉換為datetime的方法 1. 流程概述 在MySQL中&#xff0c;timestamp和datetime是兩種不同的數據類型。timestamp存儲了日期和時間&#xff0c;并且會自動更新&#xff0c;可以用于記錄數據的創建和修改時間。datetime則是一個固定的日期和時間&#xff0c;不會自…

談談高并發系統的設計方法論

談談高并發系統的設計方法論 何為高并發系統&#xff1f;什么是并發&#xff08;Conurrent&#xff09;&#xff1f;什么是高并發&#xff08;Hight Concurrnet&#xff09;&#xff1f;高并發的衡量指標有哪些&#xff1f; 實現高并發系統的兩大板塊高并發系統應用程序側的設計…

騰訊云學生服務器使用教程_申請騰訊云學生機詳細流程

2024年騰訊云學生服務器優惠活動「云校園」&#xff0c;學生服務器優惠價格&#xff1a;輕量應用服務器2核2G學生價30元3個月、58元6個月、112元一年&#xff0c;輕量應用服務器4核8G配置191.1元3個月、352.8元6個月、646.8元一年&#xff0c;CVM云服務器2核4G配置842.4元一年&…

還在用Jenkins?快來試試這款簡而輕的自動部署軟件!

最近發現了一個比 Jenkins 使用更簡單的項目構建和部署工具&#xff0c;完全可以滿足個人以及一些小企業的需求&#xff0c;分享一下。 Jpom 是一款 Java 開發的簡單輕量的低侵入式在線構建、自動部署、日常運維、項目監控軟件。 日常開發中&#xff0c;Jpom 可以解決下面這些…