Spring框架為什么采用三級緩存而不采用二級緩存來解決循環依賴?CGLIB動態代理的AOP存在! 發現每次執行一遍singleFactory.getObject()方法又是一個新的代理對象,這就會有問題了,因為AService是單例的,每次執行singleFactory.getObject()方法又會產生新的代理對象,假設這里只有一級和三級緩存的話,我每次從三級緩存中拿到singleFactory對象,執行getObject()方法又會產生新的代理對象,這是不行的,因為AService是單例的,所有這里我們要借助二級緩存來解決這個問題,將執行了singleFactory.getObject()產生的對象放到二級緩存中去,后面去二級緩存中拿,沒必要再執行一遍singletonFactory.getObject()方法再產生一個新的代理對象,保證始終只有一個代理對象。 還有一個注意的點,既然singleFactory.getObject()返回的是代理對象,那么注入的也應該是代理對象,我們可以看到注入的確實是經過CGLIB代理的AService對象。所以如果沒有AOP的話確實可以兩級緩存就可以解決循環依賴的問題,如果加上AOP,兩級緩存是無法解決的,不可能每次執行singleFactory.getObject()方法,都給我產生一個新的代理對象,所以還要借助另外一個緩存來保存產生的代理對象。
緩存解決循環依賴的思路有兩種:
第一種:不管有沒有循環依賴,都提前創建好代理對象,並將代理對象放入緩存。出現循環依賴時,其它對象直接就可以取到代理對象並注入,兩個級別的緩存就夠了。
第二種:不提前創建好代理對象,在出現循環依賴被其它對象注入時,才實時生成代理對象。
Spring選擇了后一種,如果使用兩個緩存解決循環依賴,意味着Bean在構造完成后就創建代理對象,這樣就違背了Spring的設計原則。Spring結合AOP和Bean的生命周期,是在Bean創建完成之后通過AnnotationAwareAspectJAutoProxyCreator這個后置處理器來完成的,在這個后置處理器的postProcessAfterInitialization方法中對初始化后的Bean完成AOP代理。使用第一種方案如果出現了循環依賴,那沒有辦法,只有先給Bean先創建代理,但是在Spring設計之初就是讓Bean在生命周期的最后一步完成代理而不是在實例化之后就立馬完成代理。