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

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

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

問(wèn)題背景

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

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

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

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

過(guò)程

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

定位

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

通過(guò)斷點(diǎn),可以拿到兩個(gè)信息

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

2、beanNames,也就是當(dāng)前beanFactory中所有已注冊(cè)的bean中,沒(méi)有加載到任何通過(guò)Spring的@Service注解標(biāo)識(shí)的bean,但是卻加載到了所有被Dubbo的@Service加載到的bean。

這樣一來(lái)我們可以確定的是確實(shí)存在多容器隔離,SpringCloud也會(huì)通過(guò)BootstrapApplicationListener這個(gè)監(jiān)聽(tīng)器創(chuàng)建一個(gè)IoC容器,查看官方說(shuō)明:

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要早,是它的父容器,并且它們共享同一個(gè)Environment。

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

根因

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

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

配置加載順序

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

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

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

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

解決

問(wèn)題根因找到了,想解決就比較簡(jiǎn)單了,兩種方式:

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

問(wèn)題其實(shí)比較簡(jiǎn)單,但是挺有意思,分享一下過(guò)程與思路*~*

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

相關(guān)文章

  • spring如何使用xml裝配bean

    spring如何使用xml裝配bean

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

    詳解Java中的Lambda表達(dá)式

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

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

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

    springboot后端解決跨域問(wèn)題

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

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

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

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

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

    SpringBoot框架aop切面的execution表達(dá)式解讀

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

    詳解spring cloud feign踩坑記錄

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

    Java語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單FTP軟件 FTP連接管理模塊實(shí)現(xiàn)(8)

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

    Spring高級(jí)之注解@PropertySource的原理

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

最新評(píng)論

青州市| 彭泽县| 赤城县| 濮阳市| 久治县| 夏河县| 兴隆县| 清水河县| 星子县| 长治市| 塔河县| 乐昌市| 宜君县| 长春市| 栾川县| 天台县| 治县。| 安远县| 民县| 泾阳县| 会宁县| 阿荣旗| 武安市| 海安县| 金秀| 康乐县| 左权县| 横山县| 陆丰市| 曲阜市| 湖北省| 株洲市| 崇信县| 额济纳旗| 信丰县| 宣威市| 鹤庆县| 竹山县| 江达县| 南木林县| 玛纳斯县|