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

關(guān)于Spring配置文件加載方式變化引發(fā)的異常詳解

 更新時間:2022年01月18日 11:26:47   作者:噠噠噠打代碼  
這篇文章主要給大家介紹了關(guān)于Spring配置文件加載方式變化引發(fā)的異常的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家學習或者使用Spring具有一定的參考學習價值,需要的朋友可以參考下

問題背景

我們項目的配置文件一直是通過Apollo進行管理,但是近期由于某些特殊的部署需求,需要使用K8S的原生對象來獲取配置,如此一來的話,就需要使用環(huán)境變量spring.config.location來指定application.properties文件的路徑,以便動態(tài)的獲取配置。

說明:項目是一個dubbo項目,配置文件中主要包括一些基礎(chǔ)組件的配置、以及dubbo相關(guān)的配置。

這時候問題來了,在所有配置及代碼都沒有變化的情況下,如果不指定環(huán)境變量使用本地的application.properties,則沒有異常任何,項目可以正常啟動,但是一但通過spring.config.location 來加載配置,則項目會直接啟動失敗,并報如下異常:

NoSuchBeanDefinitionException,這個異常前期誤導(dǎo)我不少時間,它一般是Spring在容器初始化時,進行依賴注入的時候沒有找到對應(yīng)的bean定義,也就意味著這個bean壓根沒有被注冊到BeanFactory中,這就很奇怪,只是配置文件的加載方式不同,為何會影響到bean的注冊?

過程

找不到bean,最常見的問題有兩種:要么是配置問題,比如掃描的包配置錯誤、配置未生效等。要么就是IoC容器的問題,存在多個容器,導(dǎo)致bean隔離。

定位

在這個問題場景下,兩種原因都有可能,不過問題可以復(fù)現(xiàn),就比較好解決。我們直接驗證一下,最簡單粗暴的法子就是斷點伺候,對比兩種配置加載方式方式的差異。我們知道除了延遲加載的bean之外,所有bean都是在org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons初始化的,那么在這個方法里以異常信息中的bean名稱,打個條件斷點看看

通過斷點,可以拿到兩個信息

1、通過當前的堆棧,可以看到當前的初始化bean邏輯并不是SpringBoot的IoC容器觸發(fā)的,而是SpringCloud

2、beanNames,也就是當前beanFactory中所有已注冊的bean中,沒有加載到任何通過Spring的@Service注解標識的bean,但是卻加載到了所有被Dubbo的@Service加載到的bean。

這樣一來我們可以確定的是確實存在多容器隔離,SpringCloud也會通過BootstrapApplicationListener這個監(jiān)聽器創(chuàng)建一個IoC容器,查看官方說明:

A Spring Cloud application operates by creating a “bootstrap” context, which is a parent context for the main application. It is responsible for loading configuration properties from the external sources and for decrypting properties in the local external configuration files. The two contexts share an Environment, which is the source of external properties for any Spring application. By default, bootstrap properties (not bootstrap.properties but properties that are loaded during the bootstrap phase) are added with high precedence, so they cannot be overridden by local configuration.

SpringCloud創(chuàng)建的容器的加載順序比SpringBoot要早,是它的父容器,并且它們共享同一個Environment。

雖然現(xiàn)在知道了異常產(chǎn)生的原因,但是為什么換了配置加載方式就會由父容器加載?根據(jù)上面的第二個信息,被Dubbo注解標識的bean都被加載了,但是這些bean依賴的SpringBean還沒有加載進來,這意味著由于配置文件加載方式的變化,導(dǎo)致Dubbo標記的bean加載時機發(fā)生的改變。

根因

那接下來就是看一下Dubbo的bean加載邏輯,我們的服務(wù)比較老了,使用的spring-boot-starter-dubbo來整合SpringBoot與Dubbo。一般spring-boot-starter都是通過@EnableXXX或spring.factories來自動裝載相關(guān)的bean,而spring-boot-starter-dubbo沒有使用@Enable,那直接找到j(luò)ar包下的spring.factories文件,找到對應(yīng)的Initializer:

它實現(xiàn)的是ApplicationContextInitiailizer,這些接口會在準備完Context環(huán)境,在prepareContext中調(diào)用,那么很明顯,父容器肯定先會執(zhí)行,子容器后執(zhí)行。 看代碼邏輯,它只有在讀取到spring.dubbo.scan有值時,才會去注冊bean,到這里原因已經(jīng)比較明顯了,使用application.properties時父容器讀不到配置,而使用spring.config.location加載配置時,父容器可以讀到配置。

配置加載順序

上面提到的SpringCloud文檔中有這么一句話:

By default, bootstrap properties (not bootstrap.properties but properties that are loaded during the bootstrap phase) are added with high precedence

那么通過spring.config.location方式加載屬性是不是在bootstrap phase中呢,直接找到SpringCloud的加載類BootstrapApplicationListener,搜索spring.config.location,發(fā)現(xiàn)它確實優(yōu)先加載

而如果是使用application.properties,那么配置文件則不會被SpringCloud加載到,會由子容器加載。

解決

問題根因找到了,想解決就比較簡單了,兩種方式:

  • 直接關(guān)閉SpringCloud的boostrap listener,通過配置spring.cloud.bootstrap.enabled=false即可
  • 這個問題其實也是dubbo的整合方式不合理導(dǎo)致的,使用Dubbo自帶的注解掃描,不使用配置文件的方式

問題其實比較簡單,但是挺有意思,分享一下過程與思路*~*

到此這篇關(guān)于Spring配置文件加載方式變化引發(fā)的異常的文章就介紹到這了,更多相關(guān)Spring配置文件加載方式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring如何使用xml裝配bean

    spring如何使用xml裝配bean

    這篇文章主要介紹了spring如何使用xml裝配bean,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • 詳解Java中的Lambda表達式

    詳解Java中的Lambda表達式

    這篇文章主要介紹了Java中的Lambda表達式的的相關(guān)資料,文中講解非常詳細,示例代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-06-06
  • zuul轉(zhuǎn)發(fā)后服務(wù)取不到請求路徑的解決

    zuul轉(zhuǎn)發(fā)后服務(wù)取不到請求路徑的解決

    這篇文章主要介紹了zuul轉(zhuǎn)發(fā)后服務(wù)取不到請求路徑的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • springboot后端解決跨域問題

    springboot后端解決跨域問題

    今天小編就為大家分享一篇關(guān)于springboot后端解決跨域問題,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • AsyncHttpClient?ChannelPool線程池頻道池源碼流程解析

    AsyncHttpClient?ChannelPool線程池頻道池源碼流程解析

    這篇文章主要為大家介紹了AsyncHttpClient ChannelPool線程池頻道池源碼流程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • 淺談String.split()遇到空字符串的幾種情況

    淺談String.split()遇到空字符串的幾種情況

    這篇文章主要介紹了淺談String.split()遇到空字符串的幾種情況,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • SpringBoot框架aop切面的execution表達式解讀

    SpringBoot框架aop切面的execution表達式解讀

    這篇文章主要介紹了SpringBoot框架aop切面的execution表達式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 詳解spring cloud feign踩坑記錄

    詳解spring cloud feign踩坑記錄

    這篇文章主要介紹了spring cloud feign踩坑記錄,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • Java語言實現(xiàn)簡單FTP軟件 FTP連接管理模塊實現(xiàn)(8)

    Java語言實現(xiàn)簡單FTP軟件 FTP連接管理模塊實現(xiàn)(8)

    這篇文章主要為大家詳細介紹了Java語言實現(xiàn)簡單FTP軟件,F(xiàn)TP連接管理模塊的實現(xiàn)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Spring高級之注解@PropertySource的原理

    Spring高級之注解@PropertySource的原理

    這篇文章主要介紹了Spring高級之注解@PropertySource的原理,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03

最新評論

吉木萨尔县| 运城市| 崇阳县| 资溪县| 灵寿县| 广州市| 阳信县| 柳江县| 扎赉特旗| 通化市| 大同市| 丽水市| 永登县| 松江区| 确山县| 互助| 宁明县| 衢州市| 巨野县| 平邑县| 息烽县| 治多县| 建平县| 德清县| 千阳县| 共和县| 怀化市| 宜良县| 六盘水市| 大英县| 九龙城区| 秀山| 二连浩特市| 句容市| 东乡县| 临城县| 刚察县| 宁海县| 蛟河市| 三穗县| 武定县|