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

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

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

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

下面的屬性來(lái)源于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中,那么問(wèn)題來(lái)了,singletonFactories的對(duì)象是什么時(shí)候放進(jìn)去的。

研究Spring構(gòu)造類實(shí)例的時(shí)候,通過(guò)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í)例之間的互相引用的問(wèn)題就清晰了

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

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