JAVA中迴圈依賴的相關問題

2021-08-11 14:19:59 字數 1086 閱讀 9561

1.類a的構造方法中建立類b,類b的構造方法中建立a,物件是如何被建立的?

public class a 

}

public class b 

}

public class testcase 

}

結果:棧溢位,很明顯,ab互相new對方死迴圈。

2.物件a持有物件b的引用,物件b持有物件a的引用,此外ab再無被引用的地方,那麼a,b會被gc**嗎?

答案肯定是會**,那麼gc通過什麼方式來**呢?

gc處理物件有一種策略是使用引用計數的方法,每個物件被持有引用就+1,gc會掃瞄所有物件的引用,如果發現引用為0的就直接**到,然而我們這種情況兩個物件互相引用,其引用數不等於0,所以引用計數策略不能解決這個問題;在gc策略中還有另一種策略通過可達性演算法,來判斷物件是否存活,演算法的基本思想是通過一系列被稱為gc roots的物件最為起始點,從這些節點開始往下搜尋,搜尋所走過的路徑稱為引用鏈,當乙個物件沒有任何引用鏈可達時證明此物件不可用。

3.spring框架中向beana中注入b,向bean b中注入a,spring是如何解決迴圈依賴的?

之前去面試,面試官問到這個問題,一直自己使用spring,spring用起來也很爽,然而spring如何建立物件,如何幫我們注入物件,如何處理存在迴圈依賴的問題,當時想了一種思路,就是在建立乙個物件的時候建立乙個標記池,沒依賴乙個就將其新增到標記池,比如說a中注入b,先將b加入標記池,再來建立b,在建立b的時候發現有需要建立a然後將a加入標記池,同理當我們再將b再次加入標記池時會發現其已存在,因此判定為迴圈引用,至此不建立第二個b。這個方法實現起來比較簡單,然而就是容易出現空指標;第二個思路是使用懶載入的方式,所有待注入的物件都是在直接呼叫的時候建立,比如說a中注入b在建立a的時候並不是直接建立a物件而是返回a的**物件,在**a的過程中我們不建立b物件,而是將getb()方法前面新增this.b = new b();通過這樣,達到只有當我們使用物件時才去建立它,因此就不存在迴圈問題了。

Spring bean的迴圈依賴問題

傳送門 通過迴圈依賴問題徹底理解 spring ioc 的精華 迴圈依賴其實就是迴圈引用,也就是兩個或則兩個以上的bean互相持有對方,最終形成閉環。比如a依賴於b,b依賴於c,c又依賴於a。spring 中的迴圈依賴有構造器迴圈依賴和setter迴圈依賴。spring容器會將當前正在建立的bean...

Spring 迴圈依賴問題

a class com.demo.circularreference.a name b ref b bean b class com.demo.circularreference.b name a ref a bean public classa public class b spring中將迴圈依...

Srping bean迴圈依賴問題

spring 為了解決單例的迴圈依賴問題,使用了 快取 遞迴呼叫時發現 bean 還在建立中即為迴圈依賴 一級快取 用於存放完全初始化好的 bean private final mapsingletonobjects new concurrenthashmap 256 二級快取 存放原始的 bean...