成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

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

瀏覽:56日期:2023-08-11 11:21:51

概述

循環(huán)依賴就是依賴關(guān)系形成環(huán),比如最簡(jiǎn)單的循環(huán)依賴:A對(duì)象依賴B,B對(duì)象依賴A

屬性注入與循環(huán)依賴

如果是構(gòu)造器注入,如果循環(huán)依賴對(duì)象沒(méi)法構(gòu)建,因?yàn)檫€未實(shí)例化 如果是屬性注入但是作用域是prototype,spring不會(huì)緩存其對(duì)象實(shí)例,也不能處理循環(huán)依賴的情況 如果是屬性注入singleton的,其bean的實(shí)例化過(guò)程與屬性注入過(guò)程是分開(kāi)的,并且spring提供了三個(gè)map(就是大家說(shuō)三級(jí)緩存)來(lái)實(shí)現(xiàn)。

spring屬性注入處理循環(huán)依賴的方式

通過(guò)以下xml方式配置一個(gè)循環(huán)依賴的示例:

<bean class='com.example.leetcode.spring.bean.Person'> <property name='parent' ref='person2'></property> <property name='name' value='tom'></property></bean><bean class='com.example.leetcode.spring.bean.Person'> <property name='parent' ref='person1'></property> <property name='name' value='jack'></property></bean>

spring循環(huán)依賴處理幾個(gè)關(guān)鍵位置:

獲取bean對(duì)象

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; // 這里會(huì)檢查單例bean是否已經(jīng)在注冊(cè)表,并返回。 // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) {logger.trace('Returning eagerly cached instance of singleton bean ’' + beanName + '’ that is not fully initialized yet - a consequence of a circular reference'); } else {logger.trace('Returning cached instance of singleton bean ’' + beanName + '’'); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } ...}

DefaultSingletonBeanRegistry(單例對(duì)象注冊(cè)表)的幾個(gè)關(guān)鍵屬性。

// 用來(lái)存儲(chǔ)已經(jīng)創(chuàng)建好的單例對(duì)象 /** Cache of singleton objects: bean name to bean instance. */ private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); // 用來(lái)存儲(chǔ)單例beanname到ObjectFactory的映射 /** Cache of singleton factories: bean name to ObjectFactory. */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); // 用來(lái)提前存儲(chǔ)還未初始化好的單例對(duì)象 /** Cache of early singleton objects: bean name to bean instance. */ private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

DefaultSingletonBeanRegistry.getSingleton()的實(shí)現(xiàn).

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;}

AbstractAutowireCapableBeanFactory.doCreateBean創(chuàng)建對(duì)象與注入屬性

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { ... instanceWrapper = createBeanInstance(beanName, mbd, args); ... // 檢查是否提前將單例bean存入緩存 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace('Eagerly caching bean ’' + beanName + '’ to allow for resolving potential circular references'); } // 這里將beanname與工廠映射放入緩存注冊(cè)表中(也就是上面的singletonFactories) addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } ... // 注入依賴屬性 populateBean(beanName, mbd, instanceWrapper); ...}

假設(shè)我們從beanfactory獲取person1對(duì)象, 循環(huán)依賴處理流程如下:

1.通過(guò)AbstractBeanFactory.doGetBean('persion1')獲取對(duì)象

2.因?yàn)橐婚_(kāi)始通過(guò)DefaultSingletonBeanRegistry.getSingleton()什么都沒(méi)有,進(jìn)入AbstractAutowireCapableBeanFactory.doCreateBean()進(jìn)行創(chuàng)建

3.AutowireCapableBeanFactory.doCreateBean()里面執(zhí)行完創(chuàng)建邏輯,因?yàn)槭莝ingleton將beanname與工廠的映射加入到addSingletonFactory()到緩存

4.開(kāi)始處理person1對(duì)象的屬性依賴populateBean()

5.當(dāng)發(fā)現(xiàn)person1的parent屬性是一個(gè)引用時(shí),通過(guò)beanfactory.getBean('person2')獲取依賴對(duì)象(org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveReference)

6.此時(shí)進(jìn)入person2的創(chuàng)建流程, person2也沒(méi)有緩存,開(kāi)始實(shí)例化并加入到addSingletonFactory()到緩存

7.person2在通過(guò)populateBean()注入屬性依賴發(fā)現(xiàn)依賴person1, 此時(shí)通過(guò)beanfactory.getBean('person1')獲取依賴對(duì)象

8.此時(shí)AbstractBeanFactory.doGetBean('persion1')獲取對(duì)象執(zhí)行到getSingleton('person1')進(jìn)行以下判斷:

從singletonObjects.get(beanName)獲取到null 進(jìn)入if條件,對(duì)singletonObjects同步 從earlySingletonObjects.get(beanName);獲取也為null 進(jìn)入內(nèi)層if,通過(guò)singletonFactories.get(beanName);獲取到最開(kāi)始bean實(shí)例化之后的beanname與工廠緩存信息 獲取到僅實(shí)例化完成的bean,并earlySingletonObjects.put(beanName, singletonObject); 然后刪除singletonFactories.remove(beanName);

9.此時(shí)從getSingleton('person1')返回了一個(gè)僅實(shí)例化尚未注入的bean引用

10.person2在第7步獲取到person1僅實(shí)例化未注入的對(duì)象引用。

11.person2完成屬性注入并返回。

12.person2被addSingleton(beanName, singletonObject);中singletonObjects.put(beanName, singletonObject)緩存,并刪除singletonFactories.remove(beanName);earlySingletonObjects.remove(beanName);

13.person1在5步獲取到person2的對(duì)象并完成屬性注入

14.person1對(duì)象返回(因?yàn)橐婚_(kāi)始person2獲取的是person1的引用,此時(shí)person1完成注入是能看到注入后的對(duì)象)

15.person1被addSingleton(beanName, singletonObject);中singletonObjects.put(beanName, singletonObject)緩存,并刪除singletonFactories.remove(beanName);earlySingletonObjects.remove(beanName);

16.返回最終的person1對(duì)象

關(guān)于三個(gè)map(三級(jí)緩存)

在出現(xiàn)循環(huán)依賴時(shí),三個(gè)map之間的流程如下:

先從singletonFactories獲取工廠,并通過(guò)getObject獲取對(duì)象并移除緩存,將對(duì)象緩存到earlySingletonObjects通過(guò)earlySingletonObjects獲取提前曝光的對(duì)象對(duì)象創(chuàng)建并初始化完成之后,對(duì)象信息保留在singletonObjects并移除過(guò)earlySingletonObjects中的緩存

earlySingletonObjects二級(jí)緩存是雞肋嗎?

earlySingletonObjects緩存的目的是,通過(guò)三級(jí)緩存在獲取對(duì)象會(huì)執(zhí)行一些列的后置處理器,通過(guò)earlySingletonObjects來(lái)緩存提升性能。

以上就是spring解決循環(huán)依賴的詳細(xì)內(nèi)容,更多關(guān)于sping 循環(huán)依賴的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Spring
相關(guān)文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
国产精品久久久久久久久久直播 | 国产亚洲成年网址在线观看| 亚洲乱码国产乱码精品精小说| 国产精品资源网| 韩国av一区| 精品国产乱码久久久久久蜜臀| 日韩综合在线视频| 亚洲免费激情| 国产精品久久久久久一区二区三区| 丰满岳乱妇一区二区三区| 美女精品在线| 国产精品高潮呻吟| 高清国产午夜精品久久久久久| 久久日韩精品| 一区二区免费看| 黄色国产精品| 日本一区二区在线不卡| 成人免费福利片| 91精品久久久久久久久99蜜臂| 一卡二卡三卡日韩欧美| 含羞草久久爱69一区| 久久久亚洲精华液精华液精华液| 国产精品影音先锋| 欧洲一区在线电影| 亚洲福利一区二区三区| 国内一区二区三区在线视频| 久久综合久久综合亚洲| 99这里只有久久精品视频| 欧美一级理论片| 国产精品888| 欧美精品自拍偷拍| 久久精品国产99| 欧美揉bbbbb揉bbbbb| 青青青伊人色综合久久| 香蕉久久国产| 亚洲国产精品欧美一二99| 欧美激情性爽国产精品17p| 337p粉嫩大胆噜噜噜噜噜91av| 成人国产亚洲欧美成人综合网| 亚洲va欧美va人人爽| 国产三区二区一区久久| 一区二区三区在线视频免费| 好看的av在线不卡观看| 中文字幕一区二区三区视频| 亚洲小说欧美另类社区| 中文字幕一区二区三区蜜月 | 色综合色狠狠天天综合色| 精品精品欲导航| 成人免费视频免费观看| 精品国产网站在线观看| 91蜜桃视频在线| 国产精品每日更新在线播放网址| 国产精品www994| 日韩毛片视频在线看| 亚洲高清不卡一区| 樱桃视频在线观看一区| 中文日韩在线| 日韩理论片在线| 一区二区三区免费看| 亚洲成人综合在线| 日本道在线观看一区二区| 奇米综合一区二区三区精品视频| 欧美制服丝袜第一页| 久草在线在线精品观看| 56国语精品自产拍在线观看| av中文字幕不卡| 国产精品区一区二区三区| 亚洲欧洲三级| 亚洲精品精品亚洲| 久久国产手机看片| 激情偷乱视频一区二区三区| 欧美一区二区福利视频| 99久久婷婷国产综合精品| 国产日韩一级二级三级| 极品少妇一区二区三区| 亚洲九九爱视频| 亚洲伊人观看| 韩日av一区二区| www日韩大片| 亚洲美女视频在线免费观看| 日韩高清不卡一区| 91精品啪在线观看国产60岁| 99久久精品99国产精品| 国产清纯白嫩初高生在线观看91 | 亚洲承认在线| 亚洲高清视频的网址| 欧美午夜免费电影| 成人av网址在线| 综合久久久久综合| 亚洲欧美精品| 麻豆一区二区三区| 欧美日韩一区中文字幕| 不卡av电影在线播放| 中文成人av在线| 国产精品乱子乱xxxx| 精品一区二区免费| 久久精品男人天堂av| 国产精品视频久久一区| 久久 天天综合| 精品美女一区二区| 亚洲精华国产欧美| 国产综合久久久久久久久久久久| 国产亚洲一区字幕| 老司机午夜精品视频| 成人激情小说网站| 亚洲一区视频在线| 欧美老肥妇做.爰bbww| 国模一区二区三区| 精品一区二区三区在线观看国产| 久久久久久亚洲综合影院红桃| 国产伦精品一区二区三区| 国产一区二区精品在线观看| 亚洲国产精品激情在线观看| 亚洲欧美日韩综合国产aⅴ| 精品在线免费视频| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 高清不卡在线观看| 亚洲人成网站在线| 欧美美女直播网站| 亚洲精品色图| 国产一区二区三区在线观看免费视频| 日本一区二区三区国色天香| 亚洲欧美日本视频在线观看| 波多野洁衣一区| 日韩专区在线视频| 中文一区一区三区高中清不卡| 在线观看视频91| 久久久综合网站| 精品亚洲国内自在自线福利| 亚洲欧美日韩系列| 久久免费视频一区| 91精品国产高清一区二区三区蜜臀| 亚洲一区欧美激情| 午夜欧美精品久久久久久久| 国产在线视频一区二区三区| 丝瓜av网站精品一区二区 | 欧美激情一区不卡| 日韩欧美一二区| 欧美日韩国产成人在线免费| 在线中文字幕一区二区| 国产偷国产偷亚洲高清97cao| 欧美有码视频| av成人免费在线观看| 国产a精品视频| 久久国产生活片100| 午夜精品久久一牛影视| 亚洲欧美韩国综合色| 中文字幕欧美日本乱码一线二线| 26uuu精品一区二区三区四区在线| 91精品国产色综合久久ai换脸| 欧美性一级生活| 在线观看视频一区| 色8久久人人97超碰香蕉987| 香蕉成人久久| 国产农村妇女精品一区二区| 亚洲一级二级| 亚洲天堂激情| 亚洲婷婷免费| 黄色国产精品| 亚洲黄色视屏| 亚洲欧洲一区二区在线观看| 国产一区二区在线观看免费播放| 欧美日韩一区二区三| 国产中文一区二区| 亚洲香蕉网站| 伊人久久久大香线蕉综合直播| 亚洲精品国产第一综合99久久| 亚洲男人天堂一区| 伊人色综合久久天天| 亚洲黄网站在线观看| 一区二区在线免费| 亚洲午夜成aⅴ人片| 亚洲国产精品久久艾草纯爱 | 欧美日韩一区二区国产| 韩国一区二区三区美女美女秀| 亚洲第一网站| 国产精品久久亚洲7777| 销魂美女一区二区三区视频在线| 久久精品30| 在线日韩国产精品| 欧美久久久久久久久中文字幕| 51精品视频一区二区三区| 日韩欧美123| 国产喂奶挤奶一区二区三区| 中文一区一区三区高中清不卡| 日本一区二区三区国色天香 | 盗摄精品av一区二区三区| 国产91高潮流白浆在线麻豆| 国产精品影音先锋| 从欧美一区二区三区| 99国产精品久久久久久久久久久| 91伊人久久大香线蕉| 欧美日本免费| 中文在线不卡| 在线观看亚洲精品| 91精品蜜臀在线一区尤物| 欧美mv日韩mv国产网站| 中文欧美字幕免费| 亚洲激情一二三区| 日本欧美一区二区|