日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

spring解決循環依賴

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

概述

循環依賴就是依賴關系形成環,比如最簡單的循環依賴:A對象依賴B,B對象依賴A

屬性注入與循環依賴

如果是構造器注入,如果循環依賴對象沒法構建,因為還未實例化 如果是屬性注入但是作用域是prototype,spring不會緩存其對象實例,也不能處理循環依賴的情況 如果是屬性注入singleton的,其bean的實例化過程與屬性注入過程是分開的,并且spring提供了三個map(就是大家說三級緩存)來實現。

spring屬性注入處理循環依賴的方式

通過以下xml方式配置一個循環依賴的示例:

<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循環依賴處理幾個關鍵位置:

獲取bean對象

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; // 這里會檢查單例bean是否已經在注冊表,并返回。 // 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(單例對象注冊表)的幾個關鍵屬性。

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

DefaultSingletonBeanRegistry.getSingleton()的實現.

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創建對象與注入屬性

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與工廠映射放入緩存注冊表中(也就是上面的singletonFactories) addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } ... // 注入依賴屬性 populateBean(beanName, mbd, instanceWrapper); ...}

假設我們從beanfactory獲取person1對象, 循環依賴處理流程如下:

1.通過AbstractBeanFactory.doGetBean('persion1')獲取對象

2.因為一開始通過DefaultSingletonBeanRegistry.getSingleton()什么都沒有,進入AbstractAutowireCapableBeanFactory.doCreateBean()進行創建

3.AutowireCapableBeanFactory.doCreateBean()里面執行完創建邏輯,因為是singleton將beanname與工廠的映射加入到addSingletonFactory()到緩存

4.開始處理person1對象的屬性依賴populateBean()

5.當發現person1的parent屬性是一個引用時,通過beanfactory.getBean('person2')獲取依賴對象(org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveReference)

6.此時進入person2的創建流程, person2也沒有緩存,開始實例化并加入到addSingletonFactory()到緩存

7.person2在通過populateBean()注入屬性依賴發現依賴person1, 此時通過beanfactory.getBean('person1')獲取依賴對象

8.此時AbstractBeanFactory.doGetBean('persion1')獲取對象執行到getSingleton('person1')進行以下判斷:

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

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

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

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

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

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

14.person1對象返回(因為一開始person2獲取的是person1的引用,此時person1完成注入是能看到注入后的對象)

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

16.返回最終的person1對象

關于三個map(三級緩存)

在出現循環依賴時,三個map之間的流程如下:

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

earlySingletonObjects二級緩存是雞肋嗎?

earlySingletonObjects緩存的目的是,通過三級緩存在獲取對象會執行一些列的后置處理器,通過earlySingletonObjects來緩存提升性能。

以上就是spring解決循環依賴的詳細內容,更多關于sping 循環依賴的資料請關注好吧啦網其它相關文章!

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品地址| 一区二区三区视频免费观看| 悠悠资源网久久精品| 免费黄色成人| 亚洲欧美日韩国产综合精品二区| 9久re热视频在线精品| 亚洲色图综合| 日韩欧美久久| 久久精品国产久精国产爱| 日韩欧美激情| 精品网站999| 青青久久av| 久久福利毛片| 国产精品一区二区av日韩在线| 欧美激情综合| 久久婷婷久久| 久久福利精品| 国产精品日本一区二区三区在线 | 欧美国产另类| 福利一区二区| 午夜久久黄色| 亚洲网址在线观看| 久久a爱视频| 欧美特黄一级| 色老板在线视频一区二区| 91精品国产调教在线观看| 好看的亚洲午夜视频在线| 亚洲午夜久久| 国际精品欧美精品| 首页国产欧美日韩丝袜| 国产日产精品_国产精品毛片| 激情中国色综合| 欧美高清不卡| 国产精品网址| 亚洲综合三区| 精品福利久久久| 亚洲无线一线二线三线区别av| 亚州国产精品| 欧洲在线一区| 国产精品1区| 99视频一区| 久久久精品区| 午夜一区在线| 国产福利一区二区三区在线播放| 欧美~级网站不卡| 久久99偷拍| 蜜臀av一区二区在线免费观看| 欧美粗暴jizz性欧美20| 亚洲欧美视频| 国产欧美一区二区三区精品酒店| 蜜臀91精品一区二区三区| 久久国内精品自在自线400部| 日韩大片在线播放| 欧美一区激情| 国产精品毛片| 电影天堂国产精品| 久久a爱视频| 五月亚洲婷婷 | 久久亚洲视频| 日产精品一区二区| 欧美精品国产白浆久久久久| 久久99伊人| 欧美日韩黑人| 一区二区三区四区日本视频| 国产日韩在线观看视频| 六月婷婷一区| 99国产精品私拍| 国产99精品| 国产精品久久久久久久免费观看 | 久久不见久久见免费视频7| 六月婷婷一区| 欧美日韩日本国产亚洲在线| 中文字幕一区久| 国产精品久久乐| 日韩三级视频| 亚洲精品乱码久久久久久蜜桃麻豆| 欧美成人日韩| 美女毛片一区二区三区四区 | 国产va在线视频| 美女精品久久| 国产伦精品一区二区三区千人斩| 日韩影院精彩在线| 日本一区二区三区视频在线看 | 天堂中文在线播放| 久久不见久久见免费视频7| 日韩av一区二区三区四区| 亚洲精品人人| 蜜臀a∨国产成人精品| 丝袜美腿亚洲色图| 日韩中文首页| 久久国产日本精品| 精品一区二区三区视频在线播放| 欧美日韩一区二区三区视频播放| 亚洲精品国产嫩草在线观看| 日韩国产精品久久久久久亚洲| 欧美精品中文字幕亚洲专区| 激情综合自拍| 国产精品国产三级国产在线观看| 欧美国产91| 99国产精品久久久久久久| av不卡在线看| 麻豆精品99| 精品中文字幕一区二区三区四区| 欧美视频久久| 日韩精品成人在线观看| 日韩超碰人人爽人人做人人添| 日韩亚洲精品在线观看| 91国内精品| 国产日韩亚洲欧美精品| 久久激情五月婷婷| 精品三区视频| 久久中文视频| 首页国产欧美日韩丝袜| 日韩精品三级| 久久wwww| 99tv成人| 日韩在线播放一区二区| 欧美一区成人| 在线天堂资源www在线污| 久久久精品日韩| 每日更新成人在线视频| 日韩福利视频导航| 精品精品国产三级a∨在线| 国产激情在线播放| 欧美中文字幕一区二区| 亚洲69av| 97精品国产一区二区三区 | 日韩av一区二| 电影91久久久| 狠狠久久婷婷| 欧美日韩一区二区国产| 日韩欧美三级| 蜜臀av在线播放一区二区三区 | 亚洲精品乱码| 免费看久久久| 国产综合激情| 亚洲一区二区三区四区电影 | 国产精品黑丝在线播放| 日韩视频在线一区二区三区 | 欧美日韩中文字幕一区二区三区| 伊人久久大香伊蕉在人线观看热v| 91精品日本| 国产拍在线视频| 婷婷激情图片久久| 欧美片网站免费| 九一国产精品| 乱一区二区av| 日韩在线观看一区二区| 中文av在线全新| 亚洲精品自拍| 天堂日韩电影| 国产欧美另类| 99国产精品久久久久久久| 精品国产一区二| 亚洲区国产区| 99久久精品费精品国产| 国产精品一卡| 视频一区二区不卡| 精品一区二区三区的国产在线观看| 在线观看免费一区二区| 精品视频91| 精品久久中文| 不卡在线一区| 国产欧美在线观看免费| 午夜精品影院| 色欧美自拍视频| 日韩高清成人在线| 亚洲激情精品| 午夜影院一区| 精品视频网站| 国产色噜噜噜91在线精品| 亚洲在线观看| 日韩欧美综合| 国产区精品区| 蜜桃视频在线观看一区| 亚洲调教视频在线观看| 四虎国产精品免费观看| 国产精品亚洲人成在99www| 在线免费观看亚洲| 欧美久久精品一级c片| 欧美xxxx中国| 国产精品第一国产精品| 婷婷综合国产| 日av在线不卡| 亚洲精品国产偷自在线观看| av资源新版天堂在线| 久久精品一本| 国产丝袜一区| 日韩av中文字幕一区二区三区| 狠狠爱www人成狠狠爱综合网| 日韩欧美视频专区| 国产va免费精品观看精品视频| 国产亚洲精品精品国产亚洲综合| 亚洲毛片在线免费| 视频在线观看一区二区三区| 欧美日韩国产综合网| 国产在线日韩| 久久精品国产大片免费观看| 一区二区精品伦理...| 欧美丰满日韩|