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

SpringBoot?容器刷新前回調(diào)ApplicationContextInitializer

 更新時間:2022年12月21日 09:26:43   作者:一灰灰  
這篇文章主要為大家介紹了SpringBoot?容器刷新前回調(diào)ApplicationContextInitializer使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

本文將作為Spring系列教程中源碼版塊的第一篇,整個源碼系列將分為兩部分進行介紹;單純的源碼解析,大概率是個吃力沒人看的事情,因此我們將結(jié)合源碼解析,一個是學(xué)習(xí)下別人的優(yōu)秀設(shè)計,一個是站在源碼的角度看一下我們除了日常的CURD之外,還可以干些啥

在Spring的啟動過程中,一系列的操作步驟中,提供了很多的擴展點,供我們來增強;簡單來說就是提供了很多的鉤子,這樣當(dāng)我們在某個節(jié)點執(zhí)行前后,想干點其他的事情時,可以很簡單的支持;

本文介紹的ApplicationContextInitializer,spring容器在刷新之前會回調(diào)這個接口,從而實現(xiàn)在spring容器未初始化前,干一些用戶希望做的事情

I. 項目準(zhǔn)備

本文創(chuàng)建的實例工程采用SpringBoot 2.2.1.RELEASE + maven 3.5.3 + idea進行開發(fā)

具體的SpringBoot項目工程創(chuàng)建就不贅述了,核心的pom文件,無需額外的依賴

配置文件 application.yml, 也沒有什么特殊的配置

源碼工程參考文末的源碼

II. 容器刷新前擴展點實例

1. 自定義ApplicationContextInitializer

當(dāng)我們希望實現(xiàn)一個自定義的上下文初始化時,非常簡單,實現(xiàn)上面這個接口就行了,如

public class ApplicationContextInitializer01 implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        System.out.println("ApplicationContextInitializer01");
    }
}

2. 擴展點注冊

上面自定義一個擴展點,如何使它生效呢?

官方提供了三種方式,如在啟動時,直接進行注冊: springApplication.addInitializers(new ApplicationContextInitializer01());

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(Application.class);
        springApplication.addInitializers(new ApplicationContextInitializer01());
        try (ConfigurableApplicationContext context = springApplication.run(args)) {
        }
    }
}

當(dāng)我們的擴展點是放在一個jar包中對外提供時,使用上面的啟動注冊方式顯然是不可行的,此時更推薦的做法就是通過Spring的SPI機制進行注冊

在資源目錄下的META-INF/spring.factories文件中進行注冊

org.springframework.context.ApplicationContextInitializer=com.git.hui.extention.context.ApplicationContextInitializer02

說明

  • 上面SPI的機制非常推薦大家使用,在之前的文章中,AutoConfiguration的注冊通常也是使用這種方式

除了上面的兩種注冊方式之外,另外還有一個配置文件的方式,在配置文件application.propertiesapplication.yml中,如下配置

context:
  initializer:
    classes: com.git.hui.extention.context.ApplicationContextInitializer03

啟動測試

上面三種注冊方式,我們實現(xiàn)三個自定義的擴展點,然后啟動之后,看一下實際輸出

上面的輸出,可以簡單的得出一個結(jié)論,不同注冊方式的優(yōu)先級(為了更合理的驗證下面的觀點,推薦大家修改下上面三個自定義擴展點名,排除掉是因為擴展名導(dǎo)致的排序問題)

  • 配置文件注冊 > SPI注冊 > 啟動時注冊

3. 執(zhí)行順序指定

對于自定義的擴展點實現(xiàn),當(dāng)存在順序關(guān)系時,我們可以通過@Order注解來實現(xiàn), 如當(dāng)上面的三個擴展點都是通過啟動方式注冊時

@Order(5)
public class ApplicationContextInitializer01 implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        System.out.println("ApplicationContextInitializer01");
    }
}
@Order(2)
public class ApplicationContextInitializer02 implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        System.out.println("ApplicationContextInitializer02");
    }
}
@Order(10)
public class ApplicationContextInitializer03 implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        System.out.println("ApplicationContextInitializer03");
    }
}
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(Application.class);
        springApplication.addInitializers(new ApplicationContextInitializer01(), new ApplicationContextInitializer02(), new ApplicationContextInitializer03());
        try (ConfigurableApplicationContext context = springApplication.run(args)) {
        }
    }
}

輸出實例如下

接著重點來了

  • 若上面的三個自定義實現(xiàn),不是相同的注冊方式,如將03采用配置文件方式進行注冊,那么01, 02 依然是啟動注冊
  • 則順序是 03 > 02 > 01
  • @Order注解修飾的順序,并不能打破 配置文件 > SPI > 啟動方式注冊的順序

關(guān)于自定義實現(xiàn)類的執(zhí)行順序,規(guī)則如下

  • 配置文件 > SPI > 啟動方式
  • 相同的注冊方式,可以通過 @Order 注解進行修飾,值越小則優(yōu)先級越高

4. 使用場景示例

最后我們再來看一下,這個擴展點到底有什么用,我們再什么場景下會用到這個呢?

一個經(jīng)常可以看到的應(yīng)用場景如通過它來指定需要激活的配置文件

public class ApplicationContextInitializer03 implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        // 指定激活prod對應(yīng)的配置文件
        configurableApplicationContext.getEnvironment().setActiveProfiles("prod");
    }
}

但是一般也很少見到有人這么干,因為直接使用配置參數(shù)就行了,那么有場景需要這么做么?

答案當(dāng)然是有的,比如現(xiàn)在廣為流行的docker容器部署,當(dāng)我們希望每次都是打同一個鏡像,然后在實際運行的時候,根據(jù)不同的環(huán)境來決定當(dāng)前鏡像到底啟用哪些配置文件,這時就有用了

比如我們通過容器的環(huán)境參數(shù) app.env 來獲取當(dāng)前運行的環(huán)境,如果是prod,則激活application-prod.yml; 如果是test,則激活application-test.yml

那么此時可以這么干

public class EenvActiveApplicationContextInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        String env = System.getenv("app.env");
        if ("prod".equalsIgnoreCase(env)) {
            configurableApplicationContext.getEnvironment().setActiveProfiles("prod");
        } else if ("test".equalsIgnoreCase(env)) {
            configurableApplicationContext.getEnvironment().setActiveProfiles("test");
        } else {
            throw new RuntimeException("非法的環(huán)境參數(shù):" + env);
        }
    }
}

5. 小結(jié)

本文作為擴展點的第一篇,通過實現(xiàn)ApplicationContextInitializer接口,從而達到在spring容器刷新之前做某些事情的目的

通常自定義的ApplicationContextInitializer有三種注冊方式,按照優(yōu)先級如下

  • 配置文件 > SPI方式 > 啟動方式注冊
  • 相同的注冊方式中,可以使用@Order注解來指定優(yōu)先級,值越小優(yōu)先級越高

最后還給出了一個可以應(yīng)用的實例場景,即如何實現(xiàn)一個鏡像在不同的環(huán)境中啟動運行

下一個擴展點我們將介紹如何通過BeanDefinitionRegistryPostProcessor來實現(xiàn)非Spring生態(tài)的Bean加載使用

III. 不能錯過的源碼和相關(guān)知識點

項目

工程:github.com/liuyueyi/sp…

源碼:github.com/liuyueyi/sp…

以上就是SpringBoot 容器刷新前回調(diào)ApplicationContextInitializer的詳細內(nèi)容,更多關(guān)于SpringBoot ApplicationContextInitializer的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入了解final在java中的應(yīng)用

    深入了解final在java中的應(yīng)用

    談到final關(guān)鍵字,想必很多人都不陌生,在使用匿名內(nèi)部類的時候可能會經(jīng)常用到final關(guān)鍵字。另外,Java中的String類就是一個final類,那么今天我們就來了解final這個關(guān)鍵字的用法。
    2019-06-06
  • Java實現(xiàn)獲取cpu、內(nèi)存、硬盤、網(wǎng)絡(luò)等信息的方法示例

    Java實現(xiàn)獲取cpu、內(nèi)存、硬盤、網(wǎng)絡(luò)等信息的方法示例

    這篇文章主要介紹了Java實現(xiàn)獲取cpu、內(nèi)存、硬盤、網(wǎng)絡(luò)等信息的方法,涉及java使用第三方j(luò)ar包針對本機硬件的cpu、內(nèi)存、硬盤、網(wǎng)絡(luò)信息等的讀取相關(guān)操作技巧,需要的朋友可以參考下
    2018-06-06
  • SpringBoot項目在啟動后自動關(guān)閉的實現(xiàn)

    SpringBoot項目在啟動后自動關(guān)閉的實現(xiàn)

    我們在寫spring?boot?web項目時,有時會遇到啟動后立即關(guān)閉的情況,?本文主要介紹了SpringBoot項目在啟動后自動關(guān)閉的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • SpringMVC使用RESTful接口案例

    SpringMVC使用RESTful接口案例

    RESTful是一種web軟件風(fēng)格,它不是標(biāo)準(zhǔn)也不是協(xié)議,它不一定要采用,只是一種風(fēng)格,它倡導(dǎo)的是一個資源定位(url)及資源操作的風(fēng)格,這篇文章主要介紹了SpringBoot使用RESTful接口
    2022-12-12
  • Java ThreadPool的使用解析

    Java ThreadPool的使用解析

    這篇文章主要介紹了Java ThreadPool的使用解析,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-10-10
  • 淺析Java設(shè)計模式編程中的單例模式和簡單工廠模式

    淺析Java設(shè)計模式編程中的單例模式和簡單工廠模式

    這篇文章主要介紹了淺析Java設(shè)計模式編程中的單例模式和簡單工廠模式,使用設(shè)計模式編寫代碼有利于團隊協(xié)作時程序的維護,需要的朋友可以參考下
    2016-01-01
  • Spring\SpringBoot配置連接數(shù)據(jù)庫的方法

    Spring\SpringBoot配置連接數(shù)據(jù)庫的方法

    最近在學(xué)習(xí)SpringBoot,第一步就是要配置數(shù)據(jù)庫,本文詳細的介紹了Spring\SpringBoot配置連接數(shù)據(jù)庫的方法,有需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • 詳細聊聊JDK中的反模式接口常量

    詳細聊聊JDK中的反模式接口常量

    這篇文章主要給大家介紹了關(guān)于JDK中反模式接口常量的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用jdk具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-01-01
  • mysql高版本(8.0+)group_by報錯的處理方法

    mysql高版本(8.0+)group_by報錯的處理方法

    本文主要介紹了mysql高版本(8.0+)group_by報錯的處理方法,這個錯誤一般發(fā)生在mysql 5.7以及 5.7以上的版本中,本文就來介紹一下兩種解決方法,感興趣的可以了解一下
    2023-09-09
  • Java的long和bigint長度對比詳解

    Java的long和bigint長度對比詳解

    在本文中小編給大家分享了關(guān)于Java的long和bigint長度比較的知識點內(nèi)容,有興趣的朋友們學(xué)習(xí)參考下。
    2019-07-07

最新評論

永安市| 东兴市| 富顺县| 永嘉县| 永善县| 铁力市| 灵璧县| 珲春市| 兴安盟| 旌德县| 林周县| 左贡县| 德清县| 安福县| 酒泉市| 农安县| 瑞安市| 普陀区| 仁化县| 华宁县| 云安县| 建平县| 九龙城区| 桂林市| 凤山县| 三亚市| 江安县| 察雅县| 平陆县| 犍为县| 海伦市| 建昌县| 南木林县| 江源县| 弥勒县| 阳新县| 伊春市| 卫辉市| 濮阳县| 星子县| 湘潭市|