日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Spring到底是如何解決循環(huán)依賴問題的??

來源: 責編: 時間:2023-11-28 09:33:33 284觀看
導讀作者 | 波哥審校 | 重樓Spring作為當前使用最廣泛的框架之一,其重要性不言而喻。所以充分理解Spring的底層實現(xiàn)原理對于咱們Java程序員來說至關重要,那么今天筆者就詳細說說Spring框架中一個核心技術點:如何解決循環(huán)依賴

作者 | 波哥wwV28資訊網(wǎng)——每日最新資訊28at.com

審校 | 重樓wwV28資訊網(wǎng)——每日最新資訊28at.com

Spring作為當前使用最廣泛的框架之一,其重要性不言而喻所以充分理解Spring的底層實現(xiàn)原理對于咱們Java程序員來說至關重要,那么今天筆者就詳細說說Spring框架中一個核心技術點:如何解決循環(huán)依賴問題?wwV28資訊網(wǎng)——每日最新資訊28at.com

wwV28資訊網(wǎng)——每日最新資訊28at.com

什么是循環(huán)依賴問題?

Spring的循環(huán)依賴問題是指在使用Spring容器管理Bean的依賴關系時,出現(xiàn)多個Bean之間相互依賴,形成一個循環(huán)的依賴關系。這意味著Bean A 依賴于Bean B,同時Bean B 也依賴于Bean A,從而形成一個循環(huán)。Spring容器需要確保這些循環(huán)依賴關系被正確解決,以避免初始化Bean時出現(xiàn)問題。wwV28資訊網(wǎng)——每日最新資訊28at.com

如果你去網(wǎng)上搜索“Spring是如何解決循環(huán)依賴問題的”,絕大部分答案都是:Spring使用三級緩存確保循環(huán)依賴的解決,包括"singletonObjects"、"earlySingletonObjects"和"singletonFactories"等緩存,以及占位符的使用等等。這當然沒有錯,可是看到這些文章的朋友們,你們真的理解了這其中的原理嗎?還是只是會背答案呢?那么今天筆者就來扒一扒Spring是如何解決這一問題的底層實現(xiàn)原理。當然要明白這個問題的底層實現(xiàn)原理,你得有一定的Spring源碼基礎才行哦。wwV28資訊網(wǎng)——每日最新資訊28at.com

現(xiàn)在假設我們有三個類,ClasssA、ClassB、ClassC,代碼如下:wwV28資訊網(wǎng)——每日最新資訊28at.com

wwV28資訊網(wǎng)——每日最新資訊28at.com

下面我們根據(jù)Spring關于Bean的生命周期管理過程進行分析:wwV28資訊網(wǎng)——每日最新資訊28at.com

假設首先實例化ClassA我們知道在ClassA實例化完成后,需要填充屬性classB,在填充classB屬性之前,會調(diào)用addSingletonFactory方法,把一個Lambda表達式添加到了singletonFactories集合中,這個Lambda表達式的代碼如下:wwV28資訊網(wǎng)——每日最新資訊28at.com

wwV28資訊網(wǎng)——每日最新資訊28at.com

wwV28資訊網(wǎng)——每日最新資訊28at.com

wwV28資訊網(wǎng)——每日最新資訊28at.com

在填充屬性時,需要獲取到classB的實例對象,也就是說會調(diào)用getBean("classB")來走classB這個bean實例的生命周期流程。wwV28資訊網(wǎng)——每日最新資訊28at.com

在獲取classB實例時首先會調(diào)用getSingleton從singletonObjects獲取(而這個singletonObjects就是我們平常所說的單例池, 其實就是個map集合):wwV28資訊網(wǎng)——每日最新資訊28at.com

wwV28資訊網(wǎng)——每日最新資訊28at.com

wwV28資訊網(wǎng)——每日最新資訊28at.com

如果單例池中沒有才會去創(chuàng)建,那么此時單例池中肯定沒有ClassB的實例,所以針對classB實例也會走一遍創(chuàng)建實例的生命周期的流程,同樣的也會把上述Lambda表達式添加到singletonFactories集合中。wwV28資訊網(wǎng)——每日最新資訊28at.com

此時singletonFactories集合中就有了classA和classB的兩個表達式。wwV28資訊網(wǎng)——每日最新資訊28at.com

但是這里我們要特別注意classB中需要填充屬性classA,所以在填充classB實例的classA屬性時,同樣需要調(diào)用getBean("classA")方法來獲取到classA的實例,在獲取classA實例時,同樣首先會調(diào)用getSingleton從單例池中獲取:wwV28資訊網(wǎng)——每日最新資訊28at.com

wwV28資訊網(wǎng)——每日最新資訊28at.com

如代碼所示,首先會根據(jù)beanName從singletonObjects獲取,也就是獲取classA,很顯然,classA還沒有放到單例池里面去,只有完全創(chuàng)建好的實例才會放到單例池里面去。可以看到代碼同時執(zhí)行
isSingletonCurrentlyInCreation,此時這個方法返回的是true,內(nèi)容如下:wwV28資訊網(wǎng)——每日最新資訊28at.com

wwV28資訊網(wǎng)——每日最新資訊28at.com

那這個isSingletonCurrentlyInCreation方法是干嘛用的呢?看方法名字就知道了,就是判斷當前這個bean是否正在創(chuàng)建中,我們在開始創(chuàng)建classA的時候就已經(jīng)把他的名字添加到singletonsCurrentlyInCreation這個集合中,表明正在創(chuàng)建classA。wwV28資訊網(wǎng)——每日最新資訊28at.com

很顯然滿足了if (singletonObject == null &&isSingletonCurrentlyInCreation(beanName))這個條件,于是就進入到if的方法體中。wwV28資訊網(wǎng)——每日最新資訊28at.com

然后從earlySingletonObjects這個集合中獲取對象,那這個earlySingletonObjects又是個啥玩意?只用singletonFactories和singletonObjects兩個緩存集合不就好了嗎?還要多此一舉使用earlySingletonObjects干啥呢?是不是感覺沒什么用?千萬別這么看,大師們考慮問題比咱們要考慮的周到,不服都不行。wwV28資訊網(wǎng)——每日最新資訊28at.com

我們這個案例中ClassA依賴ClassB和ClassC,ClassB依賴ClassA,ClassC也依賴ClassA,假如我們沒有這個earlySingletonObjects會出現(xiàn)什么情況呢?我們調(diào)用singletonFactories.get(beanName)得到前面說的classA的那個Lambda表達式,然后執(zhí)行
singletonFactory.getObject()就開始執(zhí)行這個Lambda表達式,在填充ClassB中的classA屬性時是不是相當于執(zhí)行了這個Lambda表達式獲取了這個classA對象。wwV28資訊網(wǎng)——每日最新資訊28at.com

好了,到此為止classA中的classB屬性獲取到了,接下來填充classC了,上述同樣的流程,當填充classC的classA屬性時,是不是還得從singletonFactories中獲取classA的Lambda表達式,然后再執(zhí)行那個Lambda表達式,于是執(zhí)行了兩次,正常情況下是沒有問題的,因為兩個Lambda表達式返回的結(jié)果都是classA的實例對象,但是有一種情況下就會有問題了?老鐵們此時心中肯定充滿疑惑,神馬情況呢?wwV28資訊網(wǎng)——每日最新資訊28at.com

如果執(zhí)行這個Lambda表達式返回的是classA的代理對象呢?如果執(zhí)行了兩次,是不是就表明classB中的classA屬性和classC中的classA屬性是兩個不同的對象了?這問題可就大了,那么問題又來了,神馬情況下會返回classA的代理對象?不賣關子了,直接上答案:在classA需要AOP的情況下,是需要生成代理對象的,而這個生成AOP的騷操作就是在這個Lambda表達式中實現(xiàn)的,我們下面會詳細介紹。wwV28資訊網(wǎng)——每日最新資訊28at.com

所以這里Spring使用了earlySingletonObjects這個我們稱為二級緩存的集合來暫存下,這樣在classC填充classA屬性的時候就不用再次調(diào)用lambda表達式了,是不是完美的解決了上述的問題?剩下的幾行代碼很簡單,就不多廢話了,大家自己看看就知道了。wwV28資訊網(wǎng)——每日最新資訊28at.com

總結(jié)下,Spring解決循環(huán)依賴問題其實就是使用了幾個集合類,它們分別是:singletonsCurrentlyInCreation(SetsingletonFactories(Map)earlySingletonObjects(Map)singletonObjects(Map),通過這幾個集合的相互配合,最終解決循環(huán)依賴問題。wwV28資訊網(wǎng)——每日最新資訊28at.com

作者介紹

波哥,互聯(lián)行業(yè)從業(yè)10余年,先后擔任項目總監(jiān)及架構(gòu)師。目前專攻技術,喜歡研究技術原理。技術全面,主攻Java,精通JVM底層機制及Spring全家桶底層框架原理,熟練掌握當前主流的中間件、服務網(wǎng)格等技術原理。wwV28資訊網(wǎng)——每日最新資訊28at.com


wwV28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-34591-0.htmlSpring到底是如何解決循環(huán)依賴問題的??

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 使用 sync.Cond 來協(xié)調(diào)并發(fā) goroutine 的訪問共享資源

下一篇: 聊聊 Calico BGP容器網(wǎng)絡實踐

標簽:
  • 熱門焦點
  • 官方承諾:K60至尊版將會首批升級MIUI 15

    全新的MIUI 15今天也有了消息,在官宣了K60至尊版將會搭載天璣9200+處理器和獨顯芯片X7的同時,Redmi給出了官方承諾,K60至尊重大更新首批升級,會首批推送MIUI 15。也就是說雖然
  • Rust中的高吞吐量流處理

    作者 | Noz編譯 | 王瑞平本篇文章主要介紹了Rust中流處理的概念、方法和優(yōu)化。作者不僅介紹了流處理的基本概念以及Rust中常用的流處理庫,還使用這些庫實現(xiàn)了一個流處理程序
  • 企業(yè)采用CRM系統(tǒng)的11個好處

    客戶關系管理(CRM)軟件可以為企業(yè)提供很多的好處,從客戶保留到提高生產(chǎn)力。  CRM軟件用于企業(yè)收集客戶互動,以改善客戶體驗和滿意度。  CRM軟件市場規(guī)模如今超過580
  • 如何使用JavaScript創(chuàng)建一只圖像放大鏡?

    譯者 | 布加迪審校 | 重樓如果您曾經(jīng)瀏覽過購物網(wǎng)站,可能遇到過圖像放大功能。它可以讓您放大圖像的特定區(qū)域,以便瀏覽。結(jié)合這個小小的重要功能可以大大改善您網(wǎng)站的用戶體驗
  • 多線程開發(fā)帶來的問題與解決方法

    使用多線程主要會帶來以下幾個問題:(一)線程安全問題  線程安全問題指的是在某一線程從開始訪問到結(jié)束訪問某一數(shù)據(jù)期間,該數(shù)據(jù)被其他的線程所修改,那么對于當前線程而言,該線程
  • Python異步IO編程的進程/線程通信實現(xiàn)

    這篇文章再講3種方式,同時講4中進程間通信的方式一、 Python 中線程間通信的實現(xiàn)方式共享變量共享變量是多個線程可以共同訪問的變量。在Python中,可以使用threading模塊中的L
  • 每天一道面試題-CPU偽共享

    前言:了不起:又到了每天一到面試題的時候了!學弟,最近學習的怎么樣啊 了不起學弟:最近學習的還不錯,每天都在學習,每天都在進步! 了不起:那你最近學習的什么呢? 了不起學弟:最近在學習C
  • 華為和江淮汽車合作開發(fā)百萬元問界MPV?雙方回應來了

    8月1日消息,郭明錤今天在社交平臺發(fā)文稱,華為正在和江淮汽車合作,開發(fā)售價在100萬元的問界MPV,預計在2024年第2季度量產(chǎn),銷量目標為上市首年交付5萬輛。
  • iQOO Neo8 Pro即將開售:到手價3099元起 安卓性能最強旗艦

    5月23日,iQOO如期舉行了新品發(fā)布會,全新的iQOO Neo8系列也正式與大家見面,包含iQOO Neo8和iQOO Neo8 Pro兩個版本,其中標準版搭載高通驍龍8+,而Pro版更
Top 主站蜘蛛池模板: 天水市| 乌审旗| 会昌县| 梁平县| 仲巴县| 南涧| 格尔木市| 安岳县| 贺兰县| 黄石市| 柳河县| 沛县| 广汉市| 郎溪县| 盐城市| 上犹县| 册亨县| 衡水市| 宝山区| 房产| 宁河县| 武义县| 房山区| 马公市| 怀来县| 双鸭山市| 勐海县| 石棉县| 望江县| 仪陇县| 兴隆县| 成都市| 仁寿县| 平凉市| 汶川县| 夏河县| 旺苍县| 钦州市| 静乐县| 安图县| 海原县|