spring循環(huán)依賴的解決方案

spring循環(huán)依賴的解決方案

Spring IOC循環(huán)依賴解決方案分析

這里Spring主要用了三層緩存來完成對(duì)循環(huán)依賴的實(shí)現(xiàn)。

下面的屬性來源于DefaultSingletonBeanRegistry類

    /** Cache of singleton objects: bean name --> bean instance */
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);

    /** Cache of singleton factories: bean name --> ObjectFactory */
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);

    /** Cache of early singleton objects: bean name --> bean instance */
    private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

當(dāng)獲取一個(gè)實(shí)例對(duì)象的時(shí)候,會(huì)調(diào)用此方法

    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }

先從singletonObjects 找,如果找不到會(huì)從earlySingletonObjects中查詢,再找不到去singletonFactories 中去查詢,如果找到的話會(huì)放在earlySingletonObjects中,那么問題來了,singletonFactories的對(duì)象是什么時(shí)候放進(jìn)去的。

研究Spring構(gòu)造類實(shí)例的時(shí)候,通過AbstractAutowireCapableBeanFactory的doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)方法中調(diào)用addSingletonFactory方法將A類曝光到singletonFactories中。

    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(singletonFactory, "Singleton factory must not be null");
        synchronized (this.singletonObjects) {
            if (!this.singletonObjects.containsKey(beanName)) {
                this.singletonFactories.put(beanName, singletonFactory);
                this.earlySingletonObjects.remove(beanName);
                this.registeredSingletons.add(beanName);
            }
        }
    }

Spring注入一個(gè)類的大體步驟分為兩部分,一是先完成對(duì)類的構(gòu)造工作,二是會(huì)對(duì)類的屬性進(jìn)行設(shè)置和填充
那么關(guān)于的單例的類實(shí)例之間的互相引用的問題就清晰了

假設(shè)A對(duì)象有個(gè)屬性B 則在A初始化的時(shí)候,構(gòu)造完成之后就放在了singletonFactories中,當(dāng)發(fā)現(xiàn)去set屬性的時(shí)候發(fā)現(xiàn)B沒有初始化,于是接著初始化B,設(shè)置屬性的時(shí)候在緩存中都可以拿到各自對(duì)象的引用,所以不會(huì)有循環(huán)依賴的報(bào)錯(cuò)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,545評(píng)論 19 139
  • spring針對(duì)Bean之間的循環(huán)依賴,有自己的處理方案。關(guān)鍵點(diǎn)就是三級(jí)緩存。當(dāng)然這種方案不能解決所有的問題,他只...
    數(shù)齊閱讀 13,387評(píng)論 6 23
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,268評(píng)論 6 342
  • 1.1 Spring IoC容器和bean簡介 本章介紹了Spring Framework實(shí)現(xiàn)的控制反轉(zhuǎn)(IoC)...
    起名真是難閱讀 2,670評(píng)論 0 8
  • mongodb的基礎(chǔ)就是針對(duì)文集的增刪改查,在此只列一些基礎(chǔ)的內(nèi)容 insert 正常插入: 循環(huán)插入 updat...
    OrochimaruX閱讀 173評(píng)論 0 1

友情鏈接更多精彩內(nèi)容