欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

什么是Spring循環(huán)依賴

本篇文章給大家分享的是有關(guān)什么是Spring循環(huán)依賴,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

創(chuàng)新互聯(lián)建站服務項目包括志丹網(wǎng)站建設(shè)、志丹網(wǎng)站制作、志丹網(wǎng)頁制作以及志丹網(wǎng)絡營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,志丹網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務的客戶以成都為中心已經(jīng)輻射到志丹省份的部分城市,未來相信會繼續(xù)擴大服務區(qū)域并繼續(xù)獲得客戶的支持與信任!

 

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

什么是Spring循環(huán)依賴

從字面上來理解就是A依賴B的同時B也依賴了A,就像上面這樣,或者C依賴與自己本身。體現(xiàn)到代碼層次就是這個樣子

@Component
public class A {
 // A中注入了B
 @Autowired
 private B b;
}
---
@Component
public class A {
 // A中注入了B
 @Autowired
 private B b;
}
---
// 自己依賴自己
@Component
public class C {
 // C中注入了C
 @Autowired
 private C c;
}
 

雖然體現(xiàn)形式不一樣,但是實際上都是循環(huán)依賴的問題。

 

什么情況下循環(huán)依賴可以被處理?

Spring解決循環(huán)依賴是有前置條件

  • 出現(xiàn)循環(huán)依賴的Bean必須要是單例(singleton),如果依賴prototype則完全不會有此需求。

  • 依賴注入的方式不能全是構(gòu)造器注入的方式(只能解決setter方法的循環(huán)依賴,這是錯誤的)

 
1. AB 均采用setter方法注入 結(jié)果OK

什么是Spring循環(huán)依賴

 
2. AB 均采用屬性Autowired注入 結(jié)果ok
什么是Spring循環(huán)依賴  
 
3. AB均采用構(gòu)造器方法注入 出現(xiàn)循環(huán)依賴
什么是Spring循環(huán)依賴  
 
4. A中注入B的方式為setter方法,B中注入A的方式為構(gòu)造器
什么是Spring循環(huán)依賴      
 
5. A中注入B的方式為構(gòu)造器,B中注入A的方式為setter方法。
什么是Spring循環(huán)依賴      
 
結(jié)論
依賴情況依賴注入方式是否解決
AB相互依賴(循環(huán)依賴)均采用setter方法注入
AB相互依賴(循環(huán)依賴)均采用屬性自動注入
AB相互依賴(循環(huán)依賴)均采用構(gòu)造器注入
AB相互依賴(循環(huán)依賴)A中注入B的方式為setter方法,B中注入A的方式為構(gòu)造器
AB相互依賴(循環(huán)依賴)B中注入A的方式為setter方法,A中注入B的方式為構(gòu)造器,Spring在創(chuàng)建Bean時默認會根據(jù)自然排序進行創(chuàng)建,A會先于B進行創(chuàng)建

從上面的測試結(jié)果我們可以看到,不是只有在setter方法注入的情況下循環(huán)依賴才能被解決,即使存在構(gòu)造器注入的場景下,循環(huán)依賴依然被可以被正常處理掉。

 

Spring循環(huán)依賴的通俗說

Spring bean 的創(chuàng)建,其本質(zhì)上還是一個對象的創(chuàng)建,既然是對象,一定要明白一點就是,一個完整的對象包含兩部分:當前對象實例化和對象屬性的實例化。在Spring中,對象的實例化是通過反射實現(xiàn)的,而對象的屬性則是在對象實例化之后通過一定的方式設(shè)置的。這個過程可以按照如下方式進行理解:什么是Spring循環(huán)依賴大致繪制依賴流程圖如下:什么是Spring循環(huán)依賴圖中g(shù)etBean()表示調(diào)用Spring的ApplicationContext.getBean()方法,而該方法中的參數(shù),則表示我們要嘗試獲取的目標對象。圖中的黑色箭頭表示一開始的方法調(diào)用走向,走到最后,返回了Spring中緩存的A對象之后,表示遞歸調(diào)用返回了,此時使用綠色箭頭表示。從圖中我們可以很清楚的看到,B對象的a屬性是在第三步中注入的半成品A對象,而A對象的b屬性是在第二步中注入的成品B對象,此時半成品的A對象也就變成了成品的A對象,因為其屬性已經(jīng)設(shè)置完成了。

到這里,Spring整個解決循環(huán)依賴問題的實現(xiàn)思路已經(jīng)比較清楚了。對于整體過程只要理解兩點:

  • Spring是通過遞歸的方式獲取目標bean及其所依賴的bean的;
  • Spring實例化一個bean的時候,是分兩步進行的,首先實例化目標bean,然后為其注入屬性。

結(jié)合這兩點,也就是說,Spring在實例化一個bean的時候,是首先遞歸的實例化其所依賴的所有bean,直到某個bean沒有依賴其他bean,此時就會將該實例返回,然后反遞歸的將獲取到的bean設(shè)置為各個上層bean的屬性的。

 

Spring循環(huán)依賴進階

一個對象一般創(chuàng)建過程有3部分組成:

  1. 實例化:簡單理解就是new了一個對象
  2. 屬性注入:為實例化中new出來的對象填充屬性
  3. 初始化:執(zhí)行aware接口中的方法,初始化方法,完成AOP代理

Spring是通過「三級緩存」來解決上述問題的:

  • singletonObjects:一級緩存 存儲的是所有創(chuàng)建好了的單例Bean
  • earlySingletonObjects:完成實例化,但是還未進行屬性注入及初始化的對象
  • singletonFactories:提前暴露的一個單例工廠,二級緩存中存儲的就是從這個工廠中獲取到的對象

然后接下來說下普通循環(huán)依賴跟帶AOP的循環(huán)依賴。

 
普通循環(huán)依賴圖

什么是Spring循環(huán)依賴結(jié)論:沒有進行AOP的Bean間的循環(huán)依賴 從上圖分析可以看出,這種情況下「三級緩存根本沒用」!所以不會存在什么提高了效率的說法

 
帶AOP循環(huán)依賴

帶AOP的跟不帶AOP的其實幾乎一樣,只是在三級緩存中存放的是函數(shù)式接口,在需要調(diào)用時直接返回代理對象。三級緩存存在的意義:

?  

只有真正發(fā)生循環(huán)依賴的時候,才去提前生成代理對象,否則只會創(chuàng)建一個工廠并將其放入到三級緩存中,但是不會去通過這個工廠去真正創(chuàng)建對象

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


是否可以用二級緩存而不用三級緩存?

?  

答案:不可以,違背Spring在結(jié)合AOP跟Bean的生命周期的設(shè)計!Spring結(jié)合AOP跟Bean的生命周期(看下圖)本身就是通過AnnotationAwareAspectJAutoProxyCreator這個后置處理器來完成的,在這個后置處理的postProcessAfterInitialization方法中對初始化后的Bean完成AOP代理。如果出現(xiàn)了循環(huán)依賴,那沒有辦法,只有給Bean先創(chuàng)建代理,但是沒有出現(xiàn)循環(huán)依賴的情況下,設(shè)計之初就是讓Bean在生命周期的「最后一步完成代理而不是在實例化后就立馬完成代理」。

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

使用了三級緩存的情況下,A、B的創(chuàng)建流程 什么是Spring循環(huán)依賴不使用三級緩存,直接在二級緩存中什么是Spring循環(huán)依賴結(jié)論:上面兩個流程的唯一區(qū)別在于為A對象創(chuàng)建代理的時機不同,使用三級緩存的情況下為A創(chuàng)建代理的時機是在B中需要注入A的時候,而不使用三級緩存的話在A實例化后就需要馬上為A創(chuàng)建代理然后放入到二級緩存中去。三級緩存是無法提速的!

 

回答模板

 

Spring如何解決循環(huán)依賴的

答:Spring通過三級緩存解決了循環(huán)依賴,其中一級緩存為單例池(singletonObjects),二級緩存為早期曝光對象earlySingletonObjects,三級緩存為早期曝光對象工廠(singletonFactories)。

當A、B兩個類發(fā)生循環(huán)引用時,在A完成實例化后,就使用實例化后的對象去創(chuàng)建一個對象工廠,添加到三級緩存中,如果A被AOP代理,那么通過這個工廠獲取到的就是A代理后的對象,如果A沒有被AOP代理,那么這個工廠獲取到的就是A實例化的對象。

當A進行屬性注入時,會去創(chuàng)建B,同時B又依賴了A,所以創(chuàng)建B的同時又會去調(diào)用getBean(a)來獲取需要的依賴,此時的getBean(a)會從緩存中獲?。?/p>

?  

第一步:先獲取到三級緩存中的工廠;

第二步:調(diào)用對象工工廠的getObject方法來獲取到對應的對象,得到這個對象后將其注入到B中。緊接著B會走完它的生命周期流程,包括初始化、后置處理器等。

第三步:當B創(chuàng)建完后,會將B再注入到A中,此時A再完成它的整個生命周期。至此,循環(huán)依賴結(jié)束!

?  
 

面試官:為什么要使用三級緩存呢?二級緩存能解決循環(huán)依賴嗎?

?  

答:如果要使用二級緩存解決循環(huán)依賴,意味著所有Bean在實例化后就要完成AOP代理,這樣違背了Spring設(shè)計的原則,Spring在設(shè)計之初就是通過AnnotationAwareAspectJAutoProxyCreator這個后置處理器來在Bean生命周期的最后一步來完成AOP代理,而不是在實例化后就立馬進行AOP代理。

?  
 

跟蹤核心大致流程

什么是Spring循環(huán)依賴

以上就是什么是Spring循環(huán)依賴,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降摹OM隳芡ㄟ^這篇文章學到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

新聞標題:什么是Spring循環(huán)依賴
分享鏈接:http://chinadenli.net/article48/gicshp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應網(wǎng)站、軟件開發(fā)、Google、標簽優(yōu)化、服務器托管、做網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

綿陽服務器托管