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

SpringBoot中@ConditionalOnBean實現(xiàn)原理解讀

 更新時間:2023年02月17日 09:23:03   作者:brucelwl  
這篇文章主要介紹了SpringBoot中@ConditionalOnBean實現(xiàn)原理,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

SpringBoot @ConditionalOnBean實現(xiàn)原理

在SpringBoot1.5.X時

判斷條件是OR,SpringBoot2.x變?yōu)榱薃ND

在spring 啟動過程中,會調(diào)用BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry后置處理器 調(diào)用ComponentScanAnnotationParser的parse(..)方法解析配置類,實現(xiàn)類路徑下的類文件掃描,

遍歷被掃描到的類,并通過@ComponentScan注解上指定的規(guī)則進行匹配,默認情況下,SpringBoot掃描@Component標記的類,( 但是在spring.factories中通過key org.springframework.boot.autoconfigure.EnableAutoConfiguration指定配置不會被掃描. 這些配置類會由@EnableAutoConfiguration導(dǎo)入的AutoConfigurationImportSelector來處理);

如果出現(xiàn)匹配的類還會通過ConditionEvaluator.shouldSkip(...)來判斷是否忽略這個類,這時候會過濾掉小部分無效類,但是不會在這個期間應(yīng)用@ConditionalOnBean去驗證,

因為其驗證實現(xiàn)類OnBeanCondition實現(xiàn)了接口ConfigurationCondition的getConfigurationPhase()方法,該方法返回值是一個枚舉值,用于判斷什么時期應(yīng)用這個條件驗證, shouldSkip()方法會判斷這個接口返回值,OnBeanCondition實現(xiàn)的getConfigurationPhase()返回的是ConfigurationPhase.REGISTER_BEAN,而類掃描期間只會執(zhí)行沒有實現(xiàn)ConfigurationCondition接口,或返回值為null,或為ConfigurationPhase.PARSE_CONFIGURATION的驗證器.

所以這個期間不會應(yīng)用@ConditionalOnBean去驗證. 這也可以理解因為這個時候有很多類沒有被遍歷到,現(xiàn)在執(zhí)行OnBeanCondition驗證肯定多數(shù)是false.

這也導(dǎo)致很多最終不會被實例化為Spring bean的類被包裝成BeanDefinition(實現(xiàn)類ScannedGenericBeanDefinition ),并注冊在DefaultListableBeanFactory 的成員beanDefinitionMap中,key為Bean的名稱,同時Bean的名稱會保存在List集合beanDefinitionNames中, 對于一些手動注冊的Bean的名稱會保存在List集合manualSingletonNames中,

然后對于parse(..)返回的BeanDefinition集合會遍歷調(diào)用ConfigurationClassParser的parse(...)遞歸調(diào)用, 當解析到配置中有@Bean定義的Bean,并有條件注解時,會調(diào)用ConditionEvaluator.shouldSkip(...)方法,最終調(diào)用到的是 Condition實現(xiàn)類的matches(...)方法.

而@ConditionalOnBean注解中的驗證實現(xiàn)類OnBeanCondition,最終判斷是否有指定的bean就是通過DefaultListableBeanFactory 中的beanDefinitionMap和manualSingletonNames是否包含指定的Bean的名稱來驗證的.

當然對于掃描到的無效類,在ConfigurationClassPostProcessor的processConfigBeanDefinitions(...)調(diào)用parse()方法后會調(diào)用this.reader.loadBeanDefinitions(configClasses),來判斷最終有效的BeanDefinition,這時候就會執(zhí)行OnBeanCondition, 移除beanDefinitionMap中無效的BeanDefinition. 

鑒于類路徑掃描規(guī)則和OnBeanCondition驗證實現(xiàn)原理

就可能導(dǎo)致無效問題

例如如下代碼:

C希望不存在A Bean時創(chuàng)建,B希望在C bean存在時創(chuàng)建,示例中A配置了Bean,這時B C都不應(yīng)該創(chuàng)建,但執(zhí)行結(jié)果是C確實沒有創(chuàng)建,而B卻被創(chuàng)建了.

原因就在于類掃描時,C被掃描了,導(dǎo)致beanDefinitionMap存在C 的BeanDefinition.

但是C在this.reader.loadBeanDefinitions(configClasses),中由于條件驗證不通過沒有創(chuàng)建被移除.(當然和類掃描順序也有關(guān)系,如果B能夠在C之后被掃描到,就會執(zhí)行正常,所以Spring官網(wǎng)建議通過spring.factories來配置,指定執(zhí)行順序或者在能夠確定執(zhí)行順序的情況下使用@ConditionalOnBean,但是一定不能通過文件名來控制順序)

注意點

如果將示例中的類配置到spring.factories中即時不指定順序,也能正常執(zhí)行,不會創(chuàng)建B C,這是由于spring.factories配置文件中的類并不是全部包裝成BeanDefinition然后判斷是否有效的,而是排序后封裝成ConfigurationClass通過遍歷的方式,同樣是在this.reader.loadBeanDefinitions(configClasses)方法中判斷該類是否通過條件驗證是否有效.

當執(zhí)行到B是,C還沒有被處理,所以導(dǎo)致B也不會被創(chuàng)建,(這有點屬于巧合導(dǎo)致的正確結(jié)果,所以為了安全還是要執(zhí)行順序,讓B在C之后被處理)

第二種情況, 在配置類中定義Bean,如果使用@ConditionalOnBean依賴的也是配置類中Bean,則執(zhí)行結(jié)果不可控,和配置類加載順序有關(guān)。

示例代碼如下:代碼中是希望Bean3被創(chuàng)建,但是實際上并沒有!!!

解決有兩種方式:

1 可以考慮使用@DependsOn來解決,參看Spring中@DependsOn注解的作用及實現(xiàn)原理。

2 如果一定要區(qū)分兩個配置類的先后順序,可以將這兩個類交與EnableAutoConfiguration管理和觸發(fā)。 也就是定義在META-INF\spring.factories中聲明是配置類, 然后通過@AutoConfigureBefore、AutoConfigureAfter、AutoConfigureOrder控制先后順序。 因為這三個注解只對自動配置類生效。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java將圖片至暗的實現(xiàn)方法

    java將圖片至暗的實現(xiàn)方法

    下面小編就為大家?guī)硪黄猨ava將圖片至暗的實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • Java連接redis報錯timed?out問題的解決辦法

    Java連接redis報錯timed?out問題的解決辦法

    最近項目開發(fā)中用到了Redis,下面這篇文章主要給大家介紹了關(guān)于Java連接redis報錯timed?out問題的解決辦法,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-02-02
  • 基于openeuler的DataGear部署文檔

    基于openeuler的DataGear部署文檔

    本文詳細介紹了如何在openEuler操作系統(tǒng)上安裝和配置JDK以及DataGear,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2025-03-03
  • springboot返回值轉(zhuǎn)成JSONString的處理方式

    springboot返回值轉(zhuǎn)成JSONString的處理方式

    這篇文章主要介紹了springboot返回值轉(zhuǎn)成JSONString的處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 在dos窗口中編譯和運行java文件的方法

    在dos窗口中編譯和運行java文件的方法

    這篇文章主要介紹了在dos窗口中編譯和運行java文件的方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • 詳解在Spring3中使用注解(@Scheduled)創(chuàng)建計劃任務(wù)

    詳解在Spring3中使用注解(@Scheduled)創(chuàng)建計劃任務(wù)

    本篇文章主要介紹了詳解在Spring3中使用注解(@Scheduled)創(chuàng)建計劃任務(wù),具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • java判斷用戶輸入的是否至少含有N位小數(shù)的實例

    java判斷用戶輸入的是否至少含有N位小數(shù)的實例

    下面小編就為大家分享一篇java判斷用戶輸入的是否至少含有N位小數(shù)的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • Spring實現(xiàn)動態(tài)數(shù)據(jù)源切換的方法總結(jié)

    Spring實現(xiàn)動態(tài)數(shù)據(jù)源切換的方法總結(jié)

    這篇文章主要為大家詳細介紹了一種Spring實現(xiàn)動態(tài)數(shù)據(jù)源切換的方法,文中的示例代碼講解詳細,具有一定的學(xué)習(xí)價值,感興趣的小伙伴可以跟隨小編一起了解一下
    2023-06-06
  • 簡單探索 Java 中的惰性計算

    簡單探索 Java 中的惰性計算

    這篇文章主要介紹了簡單探索 Java 中的惰性計算,惰性計算(盡可能延遲表達式求值)是許多函數(shù)式編程語言的特性。惰性集合在需要時提供其元素,無需預(yù)先計算它們,這帶來了一些好處。,需要的朋友可以參考下
    2019-06-06
  • Spring Cloud Feign的文件上傳實現(xiàn)的示例代碼

    Spring Cloud Feign的文件上傳實現(xiàn)的示例代碼

    這篇文章主要介紹了Spring Cloud Feign的文件上傳實現(xiàn)的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03

最新評論

三原县| 彝良县| 多伦县| 安吉县| 宣化县| 石屏县| 荆州市| 宣化县| 咸丰县| 吉水县| 屏东市| 萨迦县| 冀州市| 新安县| 包头市| 丹阳市| 兴安县| 丹东市| 阿巴嘎旗| 平武县| 库尔勒市| 古蔺县| 哈巴河县| 泸州市| 武定县| 论坛| 延长县| 波密县| 洛扎县| 寿光市| 宽甸| 五莲县| 平远县| 诏安县| 南涧| 宜章县| 牡丹江市| 民权县| 和顺县| 衡阳县| 鄂温|