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

如何正確控制springboot中bean的加載順序小結(jié)篇

 更新時間:2020年07月14日 09:39:01   作者:鉑賽東  
這篇文章主要介紹了如何正確控制springboot中bean的加載順序總結(jié),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

1.為什么需要控制加載順序

springboot遵從約定大于配置的原則,極大程度的解決了配置繁瑣的問題。在此基礎上,又提供了spi機制,用spring.factories可以完成一個小組件的自動裝配功能。

在一般業(yè)務場景,可能你不大關(guān)心一個bean是如何被注冊進spring容器的。只需要把需要注冊進容器的bean聲明為@Component即可,spring會自動掃描到這個Bean完成初始化并加載到spring上下文容器。

而當你在項目啟動時需要提前做一個業(yè)務的初始化工作時,或者你正在開發(fā)某個中間件需要完成自動裝配時。你會聲明自己的Configuration類,但是可能你面對的是好幾個有互相依賴的Bean。如果不加以控制,這時候可能會報找不到依賴的錯誤。

但是你明明已經(jīng)把相關(guān)的Bean都注冊進spring上下文了呀。這時候你需要通過一些手段來控制springboot中的bean加載順序。

2.幾個誤區(qū)

在正式說如何控制加載順序之前,先說2個誤區(qū)。

在標注了@Configuration的類中,寫在前面的@Bean一定會被先注冊

這個不存在的,spring在以前xml的時代,也不存在寫在前面一定會被先加載的邏輯。因為xml不是漸進的加載,而是全部parse好,再進行依賴分析和注冊。到了springboot中,只是省去了xml被parse成spring內(nèi)部對象的這一過程,但是加載方式并沒有大的改變。

利用@Order這個標注能進行加載順序的控制

嚴格的說,不是所有的Bean都可以通過@Order這個標注進行順序的控制。你把@Order這個標注加在普通的方法上或者類上一點鳥用都沒有。

@Order能控制哪些bean的加載順序呢,我們先看看官方的解釋:

{@code @Order} defines the sort order for an annotated component. Since Spring 4.0, annotation-based ordering is supported for many kinds of components in Spring, even for collection injection where the order values of the target components are taken into account (either from their target class or from their {@code @Bean} method). While such order values may influence priorities at injection points, please be aware that they do not influence singleton startup order which is an orthogonal concern determined by dependency relationships and {@code @DependsOn} declarations (influencing a runtime-determined dependency graph).

最開始@Order注解用于切面的優(yōu)先級指定;在 4.0 之后對它的功能進行了增強,支持集合的注入時,指定集合中 bean 的順序,并且特別指出了,它對于但實例的 bean 之間的順序,沒有任何影響。

目前用的比較多的有以下3點:

@Aspect
ApplicationListener
CommandLineRunner

3.如何控制

3.1@DependsOn

@DependsOn注解可以用來控制bean的創(chuàng)建順序,該注解用于聲明當前bean依賴于另外一個bean。所依賴的bean會被容器確保在當前bean實例化之前被實例化。

示例:

@Configuration
public class BeanOrderConfiguration {

 @Bean
 @DependsOn("beanB")
 public BeanA beanA(){
 System.out.println("bean A init");
 return new BeanA();
 }

 @Bean
 public BeanB beanB(){
 System.out.println("bean B init");
 return new BeanB();
 }

 @Bean
 @DependsOn({"beanD","beanE"})
 public BeanC beanC(){
 System.out.println("bean C init");
 return new BeanC();
 }

 @Bean
 @DependsOn("beanE")
 public BeanD beanD(){
 System.out.println("bean D init");
 return new BeanD();
 }

 @Bean
 public BeanE beanE(){
 System.out.println("bean E init");
 return new BeanE();
 }
}

以上代碼bean的加載順序為:

bean B init
bean A init
bean E init
bean D init
bean C init

@DependsOn的使用:

  • 直接或者間接標注在帶有@Component注解的類上面;
  • 直接或者間接標注在帶有@Bean注解的方法上面;
  • 使用@DependsOn注解到類層面僅僅在使用 component-scanning 方式時才有效,如果帶有@DependsOn注解的類通過XML方式使用,該注解會被忽略,<bean depends-on="..."/>這種方式會生效。

3.2 參數(shù)注入

@Bean標注的方法上,如果你傳入了參數(shù),springboot會自動會為這個參數(shù)在spring上下文里尋找這個類型的引用。并先初始化這個類的實例。

利用此特性,我們也可以控制bean的加載順序。

示例:

@Bean
public BeanA beanA(BeanB demoB){
 System.out.println("bean A init");
 return new BeanA();
}

@Bean
public BeanB beanB(){
 System.out.println("bean B init");
 return new BeanB();
}

以上結(jié)果,beanB先于beanA被初始化加載。

需要注意的是,springboot會按類型去尋找。如果這個類型有多個實例被注冊到spring上下文,那你就需要加上@Qualifier("Bean的名稱")來指定

3.3 利用bean的生命周期中的擴展點

在spring體系中,從容器到Bean實例化&初始化都是有生命周期的,并且提供了很多的擴展點,允許你在這些步驟時進行邏輯的擴展。

這些可擴展點的加載順序由spring自己控制,大多數(shù)是無法進行干預的。我們可以利用這一點,擴展spring的擴展點。在相應的擴展點加入自己的業(yè)務初始化代碼。從來達到順序的控制。

具體關(guān)于spring容器中大部分的可擴展點的分析,之前已經(jīng)寫了一篇文章詳細介紹了:《Springboot啟動擴展點超詳細總結(jié),再也不怕面試官問了》。

3.4 @AutoConfigureOrder

這個注解用來指定配置文件的加載順序。但是在實際測試中發(fā)現(xiàn),以下這樣使用是不生效的:

@Configuration
@AutoConfigureOrder(2)
public class BeanOrderConfiguration1 {
 @Bean
 public BeanA beanA(){
 System.out.println("bean A init");
 return new BeanA();
 }
}

@Configuration
@AutoConfigureOrder(1)
public class BeanOrderConfiguration2 {
 @Bean
 public BeanB beanB(){
 System.out.println("bean B init");
 return new BeanB();
 }
}

無論你2個數(shù)字填多少,都不會改變其加載順序結(jié)果。

那這個@AutoConfigureOrder到底是如何使用的呢。

經(jīng)過測試發(fā)現(xiàn),@AutoConfigureOrder只能改變外部依賴的@Configuration的順序。如何理解是外部依賴呢。

能被你工程內(nèi)部scan到的包,都是內(nèi)部的Configuration,而spring引入外部的Configuration,都是通過spring特有的spi文件:spring.factories

換句話說,@AutoConfigureOrder能改變spring.factories中的@Configuration的順序。

具體使用方式:

@Configuration
@AutoConfigureOrder(10)
public class BeanOrderConfiguration1 {
 @Bean
 public BeanA beanA(){
 System.out.println("bean A init");
 return new BeanA();
 }
}

@Configuration
@AutoConfigureOrder(1)
public class BeanOrderConfiguration2 {
 @Bean
 public BeanB beanB(){
 System.out.println("bean B init");
 return new BeanB();
 }
}

spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
 com.example.demo.BeanOrderConfiguration1,\
 com.example.demo.BeanOrderConfiguration2

4.總結(jié)

其實在工作中,我相信很多人碰到過復雜的依賴關(guān)系的bean加載,把這種不確定性交給spring去做,還不如我們自己去控制,這樣在閱讀代碼的時候 ,也能輕易看出bean之間的依賴先后順序。

到此這篇關(guān)于如何正確控制springboot中bean的加載順序總結(jié)的文章就介紹到這了,更多相關(guān)springboot中bean的加載順序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • jvm內(nèi)存溢出解決方法(jvm內(nèi)存溢出怎么解決)

    jvm內(nèi)存溢出解決方法(jvm內(nèi)存溢出怎么解決)

    jvm內(nèi)存溢出解決方法,詳細內(nèi)容看下面解釋
    2013-12-12
  • IDEA新手必備之各種快捷鍵詳解

    IDEA新手必備之各種快捷鍵詳解

    這篇文章主要介紹了IDEA新手必備之各種快捷鍵詳解,文中有非常詳細的快捷鍵介紹,對正在使用IDEA的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Spring Boot 中實現(xiàn)跨域的多種方式小結(jié)

    Spring Boot 中實現(xiàn)跨域的多種方式小結(jié)

    Spring Boot提供了多種方式來實現(xiàn)跨域請求,開發(fā)者可以根據(jù)具體需求選擇適合的方法,在配置時,要確保不僅考慮安全性,還要兼顧應用的靈活性和性能,本文給大家介紹Spring Boot 中實現(xiàn)跨域的多種方式,感興趣的朋友一起看看吧
    2024-01-01
  • 使用Java對URL進行編碼和解碼

    使用Java對URL進行編碼和解碼

    在互聯(lián)網(wǎng)應用中,URL(Uniform?Resource?Locator,統(tǒng)一資源定位符)是定位和訪問網(wǎng)絡資源的重要標識,然而,URL?中可能包含一些特殊字符,為了保證?URL?的有效性和兼容性,必須對?URL?進行編碼處理,所以本文給大家介紹了如何使用Java對URL進行編碼和解碼
    2025-03-03
  • 一篇文章帶你了解Java基礎-抽象

    一篇文章帶你了解Java基礎-抽象

    這篇文章主要給大家介紹了關(guān)于Java抽象定義以及舉例的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-08-08
  • java poi設置生成的word的圖片為上下型環(huán)繞以及其位置的實現(xiàn)

    java poi設置生成的word的圖片為上下型環(huán)繞以及其位置的實現(xiàn)

    這篇文章主要介紹了java poi設置生成的word的圖片為上下型環(huán)繞以及其位置的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • java 中HashCode重復的可能性

    java 中HashCode重復的可能性

    這篇文章主要介紹了java 中HashCode重復的可能性的相關(guān)資料,這里提供實例及測試代碼,需要的朋友可以參考下
    2017-07-07
  • SpringBoot帶你實現(xiàn)一個點餐小程序

    SpringBoot帶你實現(xiàn)一個點餐小程序

    有個小伙伴臨時找到我,要開發(fā)一個點餐的系統(tǒng),時間比較著急,給了2天的時間。馬馬虎虎的搞出來了,頭發(fā)掉了一撮!下面介紹下本系統(tǒng),感興趣的小伙伴,可以參考開發(fā)下
    2022-07-07
  • 詳解Java設計模式之橋接模式

    詳解Java設計模式之橋接模式

    橋接,顧名思義,就是用來連接兩個部分,使得兩個部分可以互相通訊。橋接模式將系統(tǒng)的抽象部分與實現(xiàn)部分分離解耦,使他們可以獨立的變化。本文通過示例詳細介紹了橋接模式的原理與使用,需要的可以參考一下
    2022-06-06
  • Java實現(xiàn)解析zip壓縮包并獲取文件內(nèi)容

    Java實現(xiàn)解析zip壓縮包并獲取文件內(nèi)容

    這篇文章主要為大家詳細介紹了如何利用Java語言實現(xiàn)頁面上傳一個源碼壓縮包,后端將壓縮包解壓,并獲取每個文件中的內(nèi)容,感興趣的可以動手嘗試一下
    2022-07-07

最新評論

河南省| 大城县| 南京市| 图木舒克市| 东乌珠穆沁旗| 正定县| 六枝特区| 巴里| 同心县| 元江| 滨海县| 牡丹江市| 翼城县| 青海省| 和平区| 玉溪市| 岳阳县| 柳州市| 龙海市| 扬中市| 陇川县| 长泰县| 黄龙县| 华亭县| 清丰县| 山西省| 贵州省| 乌拉特中旗| 深水埗区| 长顺县| 昔阳县| 开阳县| 怀来县| 桐梓县| 兴和县| 卫辉市| 大同市| 兰溪市| 南木林县| 东安县| 南部县|