回圈依賴問題
一個bean的創建分為如下步驟:

當創建一個簡單物件的時候,程序如下:
- 先從單例池中獲取bean,發現無 a
- 創建 a 的實體
- 為 a 賦值
- 把 a 放到單例池中

當創建一個物件并且其中有另外一個物件是就變成了這樣:

但是當在B物件中由參考了A物件,就會變成這樣:

因為A和B兩者相互參考,但是單例池中始終無法創建任一物件,所以會出現死回圈,
因此,我們需要添加一個半成品池,先把A初始化出來,放到一個半成品池中,
程序如下:
- 先從單例池中找A物件,沒有則開始創建A物件
- 實體化A物件,并放入半成品池中
- 為A物件賦值
- 賦值時發現參考了B物件 --> 實體化B物件,并放入半成品池中
- 為B物件賦值
- 賦值時發現參考了A物件,從單例池中和半成品池中找A物件,并將其賦值
- 實體化B物件,并放入單例池中
- 實體化A物件,從半成品池中移除A物件,并放入單例池中

這樣就解決了死回圈創建但是當使用了動態代理后,情況又會有所變化.
先來看一下AOP的執行程序,如圖:

在bean的創建程序中,創建動態代理的時機是在初始化之后的,如圖:

這個時候半成品池里放的是沒有代理過的A物件,當B去半成品池中獲取A物件,獲取的是動態代理前的A物件,而我們應該獲取的是動態代理后的A物件,這就會出現問題.

為了解決AOP的問題,spring又加入了一個工廠池

執行程序如下:
- 當創建A物件的時候會在工廠池中創建factory(a)
- ....
- 當給B賦值時,發現參考了A,就會去工廠池中執行
getEarlyReference 提前處理方法,生成一個動態代理后的A物件,并放入半成品池中,再賦值給B - ...
注意:
? 當實體化物件A的時候,A物件會產生與之對應的factory(a)方法,只有當某個物件參考A物件時,factory(a)方法才會被執行,從而去通過提前參考的方式創建動態代理物件放入半成品池中
如果說A物件沒有被提前參考,factory(a)方法不會執行
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/262789.html
標籤:Java
上一篇:mybatis一個有意思的東西
下一篇:trait能力在PHP中的使用
