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

Spring控制bean加載順序使用詳解

 更新時(shí)間:2024年01月03日 11:15:58   作者:你還有牽掛嗎  
在使用spring框架開發(fā)過程中,我們可能會遇到某個(gè)bean被另一個(gè)bean依賴,也就是bean-b的創(chuàng)建必須依賴bean-a等問題,類似這樣的場景還有很多,總結(jié)來說,這就涉及到bean的加載順序問題,如何解決呢,本文將給大家列舉出幾種常用的解決方案,需要的朋友可以參考下

1.誤區(qū)

1.1 使用@Order注解去設(shè)置Ben的加載順序(Order里面的數(shù)值越小優(yōu)先級越高)

分別創(chuàng)建Config1,Config2

@Component
@Order(1)
public class Config1 {
    public Config1(){
        System.out.println("Config1構(gòu)建了.........");
    }
}
 
?
@Component
@Order(2)
public class Config2 {
    public Config2(){
        System.out.println("Config2構(gòu)建了.........");
    }
}
 
?

期間我還嘗試著將@Component都改為使用@Configuration,結(jié)果仍然不變

總結(jié):嘗試過同包下,不同包下。最終測試結(jié)果為:一般情況下會按照SPring類的書寫的順序去創(chuàng)建,但是也不一定,最終其實(shí)得看你的編譯出來的文件,的Class文件到底是什么樣子的,包括操作系統(tǒng)文件的排序規(guī)則等一系列的因素。反正這個(gè)順序是不確定的。如果包的順序Config1在Config2的下面,就算Config1的@Order值小于Config2的值也沒有用。

1.2使用@AutoConfigureAfter控制Ben的加載順序(當(dāng)前配置類在指定配置類之后執(zhí)行)

@AutoConfigureBefore(當(dāng)前配置類在指定配置類之前執(zhí)行)

@AutoConfigureOrder(指定優(yōu)先級,數(shù)值越小,優(yōu)先級越高)

@Configuration
@AutoConfigureAfter(Config1.class)
public class Config2 {
    public Config2(){
        System.out.println("Config2構(gòu)建了.........");
    }
}
 
@Configuration
public class Config1 {
    public Config1(){
        System.out.println("Config1構(gòu)建了.........");
    }
}
@Configuration
@AutoConfigureAfter(Config1.class)
public class Config2 {
    public Config2(){
        System.out.println("Config2構(gòu)建了.........");
    }
}
 
@Configuration
public class Config1 {
    public Config1(){
        System.out.println("Config1構(gòu)建了.........");
    }
}
@Configuration
@AutoConfigureOrder(1)
public class Config2 {
    public Config2(){
        System.out.println("Config2構(gòu)建了.........");
    }
}
 
@Configuration
@AutoConfigureOrder(2)
public class Config1 {
    public Config1(){
        System.out.println("Config1構(gòu)建了.........");
    }
}

以上三個(gè)注解在同包和不同包都是不起作用的,和@Order是一樣的也是通過書寫順序去創(chuàng)建的。

此時(shí)這里使用@Component是不起作用的,但是上面的@Order注解就不會有影響,無聊是使用@Configurantion還是@Component都是一個(gè)效果。

解決:在resources下新建META-INF/spring.factories文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.juzi.test.config.Config2,\
com.juzi.test.config.Config1

結(jié)果我就不粘出來了,感興趣的小伙伴可以去嘗試一下。

2.正確的控制方法

2.1使用@DependsOn("Bean B")注解控制(告訴Spring容器Bean B 應(yīng)該被提前初始化)

創(chuàng)建AircraftTask、CarTask、TrainTask

目前創(chuàng)建的順序是 Aircraft -> CarTask -> Train

 理想的創(chuàng)建順序    Train -> Aircraft -> TrainCar

@Configuration
@DependsOn("trainTask")
public class AircraftTask {
    @PostConstruct
    public void init(){
        System.out.println("Aircraft獲取Train存入redis的數(shù)據(jù)..........");
    }
}
 
@Configuration
@DependsOn("aircraftTask")
public class CarTask {
    @PostConstruct
    public void init(){
        System.out.println("CarTask獲取到Aircraft的數(shù)據(jù)..........");
    }
}
 
@Configuration
public class TrainTask {
    @PostConstruct
    public void init(){
        System.out.println("Train初查詢數(shù)據(jù)存入redis..........");
    }
}

結(jié)果:和理想的結(jié)果一致

但是如果像以上這種依賴的類數(shù)量過多的話這樣寫注解容易寫錯,我們可以使用以下方法 :

2.2使用BeanDefinitionRegistryPostProcessor和ApplicationContextInitializer去控制

對這兩個(gè)類不是很熟悉的同學(xué)可以去下載Spring源碼簡單的閱讀一下。

public class CarTask {
    @PostConstruct
    public void init(){
        System.out.println("CarTask獲取到Aircraft的數(shù)據(jù)..........");
    }
}
 
public class AircraftTask {
    @PostConstruct
    public void init(){
        System.out.println("Aircraft獲取Train存入redis的數(shù)據(jù)..........");
    }
}
 
public class TrainTask {
    @PostConstruct
    public void init(){
        System.out.println("Train初查詢數(shù)據(jù)存入redis..........");
    }
}

這里不需要使用@Configuration或@Component注解,下面會對它們進(jìn)行手動的添加到容器中。

public class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
 
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        AbstractBeanDefinition beanDefinition2 = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition2.setBeanClass(TrainTask.class);
        registry.registerBeanDefinition("trainTask",beanDefinition2);
 
        AbstractBeanDefinition beanDefinition1 = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition1.setBeanClass(AircraftTask.class);
        registry.registerBeanDefinition("aircraftTask",beanDefinition1);
 
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition.setBeanClass(CarTask.class);
        registry.registerBeanDefinition("carTaskTask",beanDefinition);
        //相當(dāng)于往Spring容器初始化的時(shí)的那個(gè)List里面添加了一個(gè)Bean 只要在掃描之前執(zhí)行了postProcessBeanDefinitionRegistry 方法 那么就會安裝List里面存放的順序
        //生成Bean
    }
 
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
 
    }
}
public class MyApplicationContextInitiaLizer implements ApplicationContextInitializer {
 
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        configurableApplicationContext.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
    }
}

resources下新建META-INF/spring.factories文件 配置MyApplicationContextInitiaLizer的全限定類名即可。

#org.springframework.context.ApplicationContextInitializer=com.example.demo11.config.MyApplicationContextInitiaLizer

結(jié)果:也和預(yù)期的一致

以上就是Spring控制bean加載順序使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Spring控制bean加載順序的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • springcloud?gateway實(shí)現(xiàn)簡易版灰度路由步驟詳解

    springcloud?gateway實(shí)現(xiàn)簡易版灰度路由步驟詳解

    這篇文章主要為大家介紹了springcloud?gateway實(shí)現(xiàn)簡易版灰度路由步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Springboot中Aspect切面的實(shí)現(xiàn)方式(以記錄日志為例)

    Springboot中Aspect切面的實(shí)現(xiàn)方式(以記錄日志為例)

    這篇文章主要介紹了Springboot中Aspect切面的實(shí)現(xiàn)方式(以記錄日志為例),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 5個(gè)步驟讓你明白多線程和線程安全

    5個(gè)步驟讓你明白多線程和線程安全

    本文詳細(xì)講解了多線程和線程安全的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • Mybatis-plus的selectPage()分頁查詢不生效問題解決

    Mybatis-plus的selectPage()分頁查詢不生效問題解決

    本文主要介紹了Mybatis-plus的selectPage()分頁查詢不生效問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 使用Java第三方實(shí)現(xiàn)發(fā)送短信功能

    使用Java第三方實(shí)現(xiàn)發(fā)送短信功能

    這篇文章主要介紹了使用Java第三方實(shí)現(xiàn)發(fā)送短信功能,在一些開發(fā)中,經(jīng)常需要有給用戶發(fā)送短信接收驗(yàn)證碼的功能,那么在Java中該如何實(shí)現(xiàn)呢,今天我們就一起來看一看
    2023-03-03
  • 實(shí)現(xiàn)一個(gè)基于Servlet的hello world程序詳解步驟

    實(shí)現(xiàn)一個(gè)基于Servlet的hello world程序詳解步驟

    Java Servlet 是運(yùn)行在 Web 服務(wù)器或應(yīng)用服務(wù)器上的程序,它是作為來自 Web 瀏覽器或其他 HTTP 客戶端的請求和 HTTP 服務(wù)器上的數(shù)據(jù)庫或應(yīng)用程序之間的中間層
    2022-02-02
  • java selenium處理Iframe中的元素示例

    java selenium處理Iframe中的元素示例

    本文主要介紹java selenium處理Iframe中的元素,這里整理了相關(guān)資料并附有示例代碼和實(shí)現(xiàn)方法,有需要的小伙伴可以參考下
    2016-08-08
  • SpringBoot 使用 Ehcache 作為緩存的操作方法

    SpringBoot 使用 Ehcache 作為緩存的操作方法

    這篇文章主要介紹了SpringBoot 如何使用 Ehcache 作為緩存,我們通過添加 Ehcache 依賴、創(chuàng)建 Ehcache 配置文件并在 Spring Boot 應(yīng)用程序的配置文件中啟用 Ehcache 緩存,來配置 Ehcache 緩存,需要的朋友可以參考下
    2023-06-06
  • Java獲取接口所有實(shí)現(xiàn)類的方式詳解

    Java獲取接口所有實(shí)現(xiàn)類的方式詳解

    這篇文章主要介紹了Java獲取接口所有實(shí)現(xiàn)類的方式詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Java利用jenkins做項(xiàng)目的自動化部署

    Java利用jenkins做項(xiàng)目的自動化部署

    這篇文章主要介紹了Java利用jenkins做項(xiàng)目的自動化部署,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-06-06

最新評論