天天看點

Spring初始化bean過程(三級緩存解決循環依賴)

三級緩存

//一級緩存,用來存放初始化完成的Bean,可對外提供使用,在
         final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
        //二級緩存 ,用來提前暴露Bean,該緩存中的Bean還未完成自身的初始化過程,不可對外提供使用,待完成初始化後,會将該Bean放置一級緩存方可使用
         final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
         //三級緩存 ,用來存放建立Bean的過程,對象工廠中主要是BeanPostProcessor的調用,aop的建立過程在該緩存中
        final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
           

現有Bean(A)、Bean(B)需要建立

A中有一個屬性B

B中有一個屬性A(循環依賴)

下面是Spring建立Bean的過程

1.執行個體化一個A

2.将建立A的過程放入三級緩存(ObjectFactory)

3.初始化A中的屬性

    3.1.需要注入B,去一二三緩存中找,沒有找到

    3.2.執行個體化一個B

    3.3.将建立B的過程放入三級緩存(ObjectFactory)

    3.4.初始化B中的屬性

        3.4.1.需要注入A,去緩存中找,一二三逐級查找,最終在三級緩存中找到建立A的方法

        3.4.2.調用該方法,拿到A的半成品,将半成品A放入二級緩存,删除三級緩存中的A,傳回A

        3.4.3拿到半成品A注入到B中

    3.5.完成B的初始化,此時B中的屬性A已完成注入(注入的是一個半成品A)

    3.6.去二級緩存中拿B,不能拿到對象,繼續使用原有的B往後執行

    3.6.将B儲存到一級緩存,同時清除二級、三級緩存中的B

    3.7.将完成品B傳回,繼續完成A中的屬性B注入

4.完成A的初始化過程,此時A/B已經完成循環依賴

5.去二級緩存中拿A,能拿到對象,将二級緩存中的A替換前面的A,使用二級緩存中的A繼續後續操作

6.将A儲存到一級緩存,同時清除二級、三級緩存中的A

7.此時已完成Spring初始化Bean的循環依賴的全過程