注入方式分類:
? ? 構(gòu)造注入:? ? 直接拋異常,無法解決仪壮,bean池
? ? setter注入: 可以實現(xiàn)裕膀,利用三級緩存
? ? 非單例注入: 無法實現(xiàn)斤斧,未緩存
spring單例對象的創(chuàng)建過程:
? ? createBeanInstance:實例化捂刺,其實也就是調(diào)用對象的構(gòu)造方法實例化對象
? ? populateBean:填充屬性,這一步主要是多bean的依賴屬性進(jìn)行填充
? ? ?initializeBean:調(diào)用spring xml中的init 方法囚痴。
? 構(gòu)造器循環(huán)依賴
? ? ? ?當(dāng)我們實例化bean的時候,會將正在創(chuàng)建的bean加入到當(dāng)前創(chuàng)建bean 池中,創(chuàng)建過程中會一直保存在這個池中,如果進(jìn)行對象實例化的時候,發(fā)現(xiàn)緩存池里面已經(jīng)存在,就會拋異常
? setter注入
? ? ?采用三級緩存,在實例完成后,沒有初始化之前,暴漏bean.
? ? ?三級:基于單例工廠的緩存,進(jìn)入實例化階段的緩存.singletonFactories
? ? ?二級:實例化之后,沒初始化之前,提前暴光的單例對象的Cache
? ? ?三級: singletonObjects:完成初始化的單例對象的cache(一級緩存)
在利用構(gòu)造器實例化bean后,提前報露出來,供使用,好處?
? ? A實例化階段放入三級緩存,提前暴漏->依賴B->實例化B->初始化->發(fā)現(xiàn)依賴->三級緩存獲取A->B初始化完成->B放一級緩存->A初始化依賴B完成
? ?當(dāng)A對象實例化后,放到singletonFactories 里面.然后進(jìn)行初始化,發(fā)現(xiàn)自己依賴B,發(fā)現(xiàn)B還沒有被create
? ?就去創(chuàng)建B,創(chuàng)建B,首先實例化B,實例化B,之后進(jìn)行初始化,發(fā)現(xiàn)依賴A,就會從一級緩存singletonObjects獲取(沒有,A還沒有初始化)
? ,之后嘗試從二級緩存earlySingletonObjects獲取,也沒有,嘗試從三級緩存獲取,由于A實例化階段在三級緩存暴漏,
? ? 這樣就get到了A.(ObjectFactory.getObject),B拿到A對象后,就完成自己的初始化,然后將自己放進(jìn)一級緩存.
? 這樣B就完成了創(chuàng)建,然后返回到A中,A能從一級緩存中獲取到B,順利完成自己的初始化,之后,把自己放進(jìn)一級緩存.
? 由于B對象前期初始化的時候拿到了A的引用,所以現(xiàn)在B中獲取的A也完成了初始化
非單例循環(huán)依賴?
? 非單例的bean,在創(chuàng)建的時候沒有進(jìn)行緩存,無法提前暴漏,無法完成循環(huán)依賴