欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

引言

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

在Spring的啟動(dòng)過(guò)程中,一系列的操作步驟中,提供了很多的擴(kuò)展點(diǎn),供我們來(lái)增強(qiáng);簡(jiǎn)單來(lái)說(shuō)就是提供了很多的鉤子,這樣當(dāng)我們?cè)谀硞€(gè)節(jié)點(diǎn)執(zhí)行前后,想干點(diǎn)其他的事情時(shí),可以很簡(jiǎn)單的支持;

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

I. 項(xiàng)目準(zhǔn)備

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

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

配置文件 application.yml, 也沒(méi)有什么特殊的配置

源碼工程參考文末的源碼

II. 容器刷新前擴(kuò)展點(diǎn)實(shí)例

1. 自定義ApplicationContextInitializer

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

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

2. 擴(kuò)展點(diǎn)注冊(cè)

上面自定義一個(gè)擴(kuò)展點(diǎn),如何使它生效呢?

官方提供了三種方式,如在啟動(dòng)時(shí),直接進(jìn)行注冊(cè): 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)我們的擴(kuò)展點(diǎn)是放在一個(gè)jar包中對(duì)外提供時(shí),使用上面的啟動(dòng)注冊(cè)方式顯然是不可行的,此時(shí)更推薦的做法就是通過(guò)Spring的SPI機(jī)制進(jìn)行注冊(cè)

在資源目錄下的META-INF/spring.factories文件中進(jìn)行注冊(cè)

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

說(shuō)明

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

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

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

啟動(dòng)測(cè)試

上面三種注冊(cè)方式,我們實(shí)現(xiàn)三個(gè)自定義的擴(kuò)展點(diǎn),然后啟動(dòng)之后,看一下實(shí)際輸出

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

  • 配置文件注冊(cè) > SPI注冊(cè) > 啟動(dòng)時(shí)注冊(cè)

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

對(duì)于自定義的擴(kuò)展點(diǎn)實(shí)現(xiàn),當(dāng)存在順序關(guān)系時(shí),我們可以通過(guò)@Order注解來(lái)實(shí)現(xiàn), 如當(dāng)上面的三個(gè)擴(kuò)展點(diǎn)都是通過(guò)啟動(dòng)方式注冊(cè)時(shí)

@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)) {
        }
    }
}

輸出實(shí)例如下

接著重點(diǎn)來(lái)了

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

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

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

4. 使用場(chǎng)景示例

最后我們?cè)賮?lái)看一下,這個(gè)擴(kuò)展點(diǎn)到底有什么用,我們?cè)偈裁磮?chǎng)景下會(huì)用到這個(gè)呢?

一個(gè)經(jīng)??梢钥吹降膽?yīng)用場(chǎng)景如通過(guò)它來(lái)指定需要激活的配置文件

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

但是一般也很少見(jiàn)到有人這么干,因?yàn)橹苯邮褂门渲脜?shù)就行了,那么有場(chǎng)景需要這么做么?

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

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

那么此時(shí)可以這么干

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é)

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

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

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

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

下一個(gè)擴(kuò)展點(diǎn)我們將介紹如何通過(guò)BeanDefinitionRegistryPostProcessor來(lái)實(shí)現(xiàn)非Spring生態(tài)的Bean加載使用

III. 不能錯(cuò)過(guò)的源碼和相關(guān)知識(shí)點(diǎn)

項(xiàng)目

工程:github.com/liuyueyi/sp…

源碼:github.com/liuyueyi/sp…

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

相關(guān)文章

  • JavaEE實(shí)現(xiàn)前后臺(tái)交互的文件上傳與下載

    JavaEE實(shí)現(xiàn)前后臺(tái)交互的文件上傳與下載

    這篇文章主要介紹了JavaEE實(shí)現(xiàn)前后臺(tái)交互的文件上傳與下載,分享相關(guān)技術(shù),實(shí)現(xiàn)文件上傳下載功能,需要的朋友可以參考下
    2015-11-11
  • Java中的線程死鎖是什么?如何避免?

    Java中的線程死鎖是什么?如何避免?

    這篇文章主要介紹了Java中線程死鎖的相關(guān)資料,以及避免死鎖的方法,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-09-09
  • Java中JDBC的使用教程詳解

    Java中JDBC的使用教程詳解

    Java語(yǔ)言操作數(shù)據(jù)庫(kù)?JDBC本質(zhì):其實(shí)是官方(sun公司)定義的一套操作所有關(guān)系型數(shù)據(jù)庫(kù)的規(guī)則,即接口。本文講解了JDBC的使用方法,需要的可以參考一下
    2022-06-06
  • IDEA下SpringBoot指定環(huán)境、配置文件啟動(dòng)操作過(guò)程

    IDEA下SpringBoot指定環(huán)境、配置文件啟動(dòng)操作過(guò)程

    這篇文章主要介紹了IDEA下SpringBoot指定環(huán)境、配置文件啟動(dòng)過(guò)程,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • IDEA設(shè)置背景為自定義照片的操作方法

    IDEA設(shè)置背景為自定義照片的操作方法

    這篇文章主要介紹了IDEA設(shè)置背景為自定義照片,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • JUC中的wait與notify方法實(shí)現(xiàn)原理詳解

    JUC中的wait與notify方法實(shí)現(xiàn)原理詳解

    這篇文章主要介紹了JUC中的wait與notify方法實(shí)現(xiàn)原理,在進(jìn)行wait()之前,就代表著需要爭(zhēng)奪Synchorized,而Synchronized代碼塊通過(guò)javap生成的字節(jié)碼中包含monitor?enter和monitor?exit兩個(gè)指令
    2023-03-03
  • Spring中@Autowire注入的深入講解

    Spring中@Autowire注入的深入講解

    這篇文章主要給大家介紹了關(guān)于Spring中@Autowire注入的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • springboot寶塔簡(jiǎn)單部署的實(shí)現(xiàn)示例

    springboot寶塔簡(jiǎn)單部署的實(shí)現(xiàn)示例

    通過(guò)使用Spring Boot,可以快速構(gòu)建出高效、可擴(kuò)展的應(yīng)用程序,而寶塔面板則提供了簡(jiǎn)單易用的網(wǎng)站管理和維護(hù)工具,本文將詳細(xì)介紹如何將Spring Boot應(yīng)用程序與寶塔面板進(jìn)行集成,實(shí)現(xiàn)自動(dòng)化部署、配置管理等操作
    2023-11-11
  • springboot 在linux后臺(tái)運(yùn)行的方法

    springboot 在linux后臺(tái)運(yùn)行的方法

    這篇文章主要介紹了springboot 在linux后臺(tái)運(yùn)行的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-06-06
  • MyEclipse如何將項(xiàng)目的開(kāi)發(fā)環(huán)境與服務(wù)器的JDK 版本保持一致

    MyEclipse如何將項(xiàng)目的開(kāi)發(fā)環(huán)境與服務(wù)器的JDK 版本保持一致

    我們使用MyEclipse開(kāi)發(fā)Java項(xiàng)目開(kāi)發(fā)中,偶爾會(huì)遇到因項(xiàng)目開(kāi)發(fā)環(huán)境不協(xié)調(diào),導(dǎo)致這樣那樣的問(wèn)題,在這里以把所有環(huán)境調(diào)整為JDK1.6 為例,給大家詳細(xì)介紹MyEclipse如何將項(xiàng)目的開(kāi)發(fā)環(huán)境與服務(wù)器的JDK 版本保持一致,需要的朋友參考下吧
    2024-04-04

最新評(píng)論