AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

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

Spring到底是如何解決循環依賴問題的??

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

作者 | 波哥9kc28資訊網——每日最新資訊28at.com

審校 | 重樓9kc28資訊網——每日最新資訊28at.com

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

9kc28資訊網——每日最新資訊28at.com

什么是循環依賴問題?

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

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

現在假設我們有三個類,ClasssA、ClassB、ClassC,代碼如下:9kc28資訊網——每日最新資訊28at.com

9kc28資訊網——每日最新資訊28at.com

下面,我們根據Spring關于Bean的生命周期管理過程進行分析:9kc28資訊網——每日最新資訊28at.com

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

9kc28資訊網——每日最新資訊28at.com

9kc28資訊網——每日最新資訊28at.com

9kc28資訊網——每日最新資訊28at.com

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

在獲取classB實例時首先會調用getSingleton從singletonObjects獲?。ǘ@個singletonObjects就是我們平常所說的單例池, 其實就是個map集合):9kc28資訊網——每日最新資訊28at.com

9kc28資訊網——每日最新資訊28at.com

9kc28資訊網——每日最新資訊28at.com

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

此時singletonFactories集合中就有了classA和classB的兩個表達式。9kc28資訊網——每日最新資訊28at.com

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

9kc28資訊網——每日最新資訊28at.com

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

9kc28資訊網——每日最新資訊28at.com

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

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

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

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

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

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

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

總結下,Spring解決循環依賴問題其實就是使用了幾個集合類,它們分別是:singletonsCurrentlyInCreation(Set、singletonFactories(Map)、earlySingletonObjects(Map)、singletonObjects(Map),通過這幾個集合的相互配合,最終解決循環依賴問題。9kc28資訊網——每日最新資訊28at.com

作者介紹

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


9kc28資訊網——每日最新資訊28at.com

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

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

上一篇: 使用 sync.Cond 來協調并發 goroutine 的訪問共享資源

下一篇: 聊聊 Calico BGP容器網絡實踐

標簽:
  • 熱門焦點
  • K60 Pro官方停產 第三方瞬間漲價

    雖然沒有官方宣布,但Redmi的一些高管也已經透露了,Redmi K60 Pro已經停產且不會補貨,這一切都是為了即將到來的K60 Ultra鋪路,屬于廠家的正常操作。但有意思的是該機在停產之后
  • 官方承諾:K60至尊版將會首批升級MIUI 15

    全新的MIUI 15今天也有了消息,在官宣了K60至尊版將會搭載天璣9200+處理器和獨顯芯片X7的同時,Redmi給出了官方承諾,K60至尊重大更新首批升級,會首批推送MIUI 15。也就是說雖然
  • 2023年Q2用戶偏好榜:12+256G版本成新主流

    3月份的性能榜、性價比榜和好評榜之后,就要輪到2023年的第二季度偏好榜了,上半年的新機潮已經過去,最明顯的肯定就是大內存和存儲的機型了,另外部分中端機也取消了屏幕塑料支架
  • 太卷!Redmi MAX 100英寸電視便宜了:12999元買Redmi史上最大屏

    8月5日消息,從小米商城了解到,Redmi MAX 100英寸巨屏電視日前迎來官方優惠,到手價12999元,比發布價便宜了7000元,在大屏電視市場開卷。據了解,Redmi MAX 100
  • 如何正確使用:Has和:Nth-Last-Child

    我們可以用CSS檢查,以了解一組元素的數量是否小于或等于一個數字。例如,一個擁有三個或更多子項的grid。你可能會想,為什么需要這樣做呢?在某些情況下,一個組件或一個布局可能會
  • 10天營收超1億美元,《星鐵》比《原神》差在哪?

    來源:伯虎財經作者:陳平安即便你沒玩過《原神》,你一定聽說過的它的大名。恨它的人把《原神》開服那天稱作是中國游戲史上最黑暗的一天,有粉絲因為索尼在PS平臺上線《原神》,怒而
  • 大廠卷向扁平化

    來源:新熵作者丨南枝 編輯丨月見大廠職級不香了。俗話說,兵無常勢,水無常形,互聯網企業調整職級體系并不稀奇。7月13日,淘寶天貓集團啟動了近年來最大的人力制度改革,目前已形成一
  • 郭明錤稱華為和江淮汽車合作開發問界MPV,定價100萬左右、計劃明年量產

    8 月 1 日消息,郭明錤今天在 Medium 平臺發布博文,稱華為正在和江淮汽車合作,開發售價在 100 萬元的問界 MPV,預計在 2024 年第 2 季度量產,銷量目標為
  • AI芯片初創公司Tenstorrent獲三星和現代1億美元投資

    Tenstorrent是一家由芯片行業資深人士Jim Keller領導的加拿大初創公司,專注于開發人工智能芯片,該公司周三表示,已經從現代汽車集團和三星投資基金等
Top