bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

Spring循環(huán)依賴源碼解析(深度理解)-創(chuàng)新互聯(lián)

文章目錄
  • 前言
  • 本章目標
  • 一、什么是循環(huán)依賴?
    • 1、那么循環(huán)依賴是個問題嗎?
    • 2、但是在Spring中循環(huán)依賴就是一個問題了,為什么?
  • 二、Bean的生命周期
    • 2.1、在Spring中,Bean是如何生成的?
    • 2.2、那么這個注入過程是怎樣的?
    • 2.3、Srping的依賴注入如何產(chǎn)生的?
  • 三、什么是AOP
  • 四、Spring三級緩存
  • 五、Spring循環(huán)依賴的實現(xiàn)原理、源碼解析
    • 5.1、解決循環(huán)依賴思路分析
    • 5.2、Spring為什么需要三級緩存(singletonFactories)呢?
    • 5.3、Spring是如何解決循環(huán)依賴的
    • 5.4、什么時候會調(diào)用getEarlyBeanReference方法呢?
    • 5.5、如果提前進行了AOP,什么時候把AOP的代理對象放到單例池呢?
  • 六、三級緩存總結(jié)
    • 6.1、singletonObjects(一級緩存)
    • 6.2、earlySingletonObjects(二級緩存)
    • 6.3、singletonFactories(三級緩存)
    • 6.4、earlyProxyReferences(是否進行了AOP緩存)
  • 七、什么場景下spring循環(huán)依賴不行
    • 7.1、循環(huán)依賴的2個類都為原型Bean
    • 7.2、構(gòu)造方法注入
    • 7.3、如何處理構(gòu)造方法注入解決?
  • 八、spring只用二級循環(huán)能否解決循環(huán)依賴問題?
    • 8.1、為什么需要singletonFactories?
    • 8.2、那如果沒有singletonFactories,該如何把原始對象或AOP之后的代理對象放入earlySingletonObjects中呢?何時放入呢?
  • 九、循環(huán)依賴流程圖

為興安盟烏蘭浩特等地區(qū)用戶提供了全套網(wǎng)頁設計制作服務,及興安盟烏蘭浩特網(wǎng)站建設行業(yè)解決方案。主營業(yè)務為成都網(wǎng)站設計、網(wǎng)站制作、興安盟烏蘭浩特網(wǎng)站設計,以傳統(tǒng)方式定制建設網(wǎng)站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!
前言
本章目標

1、弄清楚什么是循環(huán)依賴?Spring的循環(huán)依賴是如何產(chǎn)生的?
2、Spring的循環(huán)依賴底層實現(xiàn)邏輯
3、Spring的三級緩存,每一級緩存分別干了啥,解決什么問題
4、Spring二級緩存能否搞定循環(huán)依賴?
5、Spring循環(huán)依賴什么場景搞不定


一、什么是循環(huán)依賴?

就是A對象依賴了B對象,B對象依賴了A對象。

比如:

// A依賴了B
class A{public B b;
}

// B依賴了A
class B{public A a;
}
1、那么循環(huán)依賴是個問題嗎?

如果不考慮Spring,循環(huán)依賴并不是問題,因為對象之間相互依賴是很正常的事情。

比如

A a = new A();
B b = new B();

a.b = b;
b.a = a;

這樣,A,B就依賴上了。


2、但是在Spring中循環(huán)依賴就是一個問題了,為什么?

因為,在Spring中,一個對象并不是簡單new出來了,而是會經(jīng)過一系列的Bean的生命周期,就是因為Bean的生命周期所以才會出現(xiàn)循環(huán)依賴問題。

當然,在Spring中,出現(xiàn)循環(huán)依賴的場景很多,有的場景Spring自動幫我們解決了,而有的場景則需要程序員來解決。

要明白Spring中的循環(huán)依賴,得先明白Spring中Bean的生命周期。


二、Bean的生命周期

這里不會對Bean的生命周期進行詳細的描述,只描述一下大概的過程。

PS:如需詳細了解,可以點擊傳送門:Spring Bean生命周期文章來了解Spring Bean生命周期詳細流程。


2.1、在Spring中,Bean是如何生成的?

被Spring管理的對象叫做Bean。Bean的生成步驟如下:

1、Spring掃描class得到BeanDefinition

2、根據(jù)得到的BeanDefinition去生成bean

3、首先根據(jù)class推斷構(gòu)造方法

4、根據(jù)推斷出來的構(gòu)造方法,反射,得到一個對象(暫時叫做原始對象)

5、填充原始對象中的屬性(依賴注入)

6、如果原始對象中的某個方法被AOP了,那么則需要根據(jù)原始對象生成一個代理對象

7、把最終生成的代理對象放入單例池(源碼中叫做singletonObjects)中,下次getBean時就直接從單例池拿即可

可以看到,對于Spring中的Bean的生成過程,步驟還是很多的,并且不僅僅只有上面的7步,還有很多很多,比如Aware回調(diào)、初始化等等,這里不詳細討論。

可以發(fā)現(xiàn),在Spring中,構(gòu)造一個Bean,包括了new這個步驟(第4步構(gòu)造方法反射)。

得到一個原始對象后,Spring需要給對象中的屬性進行依賴注入


2.2、那么這個注入過程是怎樣的?

比如上文說的A類,A類中存在一個B類的b屬性,

所以,

1、當A類生成了一個原始對象之后,就會去給b屬性去賦值,

2、此時就會根據(jù)b屬性的類型和屬性名去BeanFactory中去獲取B類所對應的單例bean。

3、如果此時BeanFactory中存在B對應的Bean,那么直接拿來賦值給b屬性;

4、如果此時BeanFactory中不存在B對應的Bean,則需要生成一個B對應的Bean,然后賦值給b屬性。

問題就出現(xiàn)在第二種情況,


2.3、Srping的依賴注入如何產(chǎn)生的?

如果此時B類在BeanFactory中還沒有生成對應的Bean,那么就需要去生成,就會經(jīng)過B的Bean的生命周期。

那么在創(chuàng)建B類的Bean的過程中,如果B類中存在一個A類的a屬性,那么在創(chuàng)建B的Bean的過程中就需要A類對應的Bean,

但是,觸發(fā)B類Bean的創(chuàng)建的條件是A類Bean在創(chuàng)建過程中的依賴注入,所以這里就出現(xiàn)了循環(huán)依賴:

ABean創(chuàng)建–>依賴了B屬性–>觸發(fā)BBean創(chuàng)建—>B依賴了A屬性—>需要ABean(但ABean還在創(chuàng)建過程中)

從而導致ABean創(chuàng)建不出來,BBean也創(chuàng)建不出來。

這是循環(huán)依賴的場景,但是上文說了,在Spring中,通過某些機制幫開發(fā)者解決了部分循環(huán)依賴的問題,這個機制就是三級緩存。


三、什么是AOP

在了解為什么spring 循環(huán)依賴需要緩存之前,需要對aop有一個大概的了解

AOP就是通過一個BeanPostProcessor來實現(xiàn)的,這個BeanPostProcessor就是AnnotationAwareAspectJAutoProxyCreator,它的父類是AbstractAutoProxyCreator。

而在Spring中AOP利用的要么是JDK動態(tài)代理,要么CGLib的動態(tài)代理,所以如果給一個類中的某個方法設置了切面,那么這個類最終就需要生成一個代理對象。

一般過程就是:

A類—>生成一個普通對象–>屬性注入–>基于切面生成一個代理對象–>把代理對象放入singletonObjects單例池中。

而AOP可以說是Spring中除開IOC的另外一大功能,而循環(huán)依賴又是屬于IOC范疇的,所以這兩大功能想要并存,Spring需要特殊處理。

如何處理的,就是利用了第三級緩存singletonFactories。


四、Spring三級緩存

這里先有個簡單印象,三級緩存是通用的叫法。

一級緩存為:singletonObjects

二級緩存為:earlySingletonObjects

三級緩存為:singletonFactories

先稍微解釋一下這三個緩存的作用,后面詳細分析:

singletonObjects中緩存的是已經(jīng)經(jīng)歷了完整生命周期的bean對象。

earlySingletonObjects比singletonObjects多了一個early,表示緩存的是早期的bean對象。

早期是什么意思?表示Bean的生命周期還沒走完就把這個Bean放入了earlySingletonObjects。

singletonFactories中緩存的是ObjectFactory,表示對象工廠,表示用來創(chuàng)建早期bean對象的工廠。


五、Spring循環(huán)依賴的實現(xiàn)原理、源碼解析 5.1、解決循環(huán)依賴思路分析

先來分析為什么緩存能解決循環(huán)依賴。

上文分析得到,之所以產(chǎn)生循環(huán)依賴的問題,主要是:

A創(chuàng)建時—>需要B---->B去創(chuàng)建—>需要A,從而產(chǎn)生了循環(huán)
在這里插入圖片描述
那么如何打破這個循環(huán),加個中間人(緩存)

在這里插入圖片描述

A的Bean在創(chuàng)建過程中,在進行依賴注入之前,

1、先把A的原始Bean放入緩存(提早暴露,只要放到緩存了,其他Bean需要時就可以從緩存中拿了)

2、放入緩存后,再進行依賴注入,此時A的Bean依賴了B的Bean,如果B的Bean不存在,則需要創(chuàng)建B的Bean,

3、而創(chuàng)建B的Bean的過程和A一樣,也是先創(chuàng)建一個B的原始對象,然后把B的原始對象提早暴露出來放入緩存中

4、然后在對B的原始對象進行依賴注入A,此時能從緩存中拿到A的原始對象(雖然是A的原始對象,還不是最終的Bean),B的原始對象依賴注入完了之后,B的生命周期結(jié)束,那么A的生命周期也能結(jié)束。

因為整個過程中,都只有一個A原始對象,所以對于B而言,就算在屬性注入時,注入的是A原始對象,也沒有關系,因為A原始對象在后續(xù)的生命周期中在堆中沒有發(fā)生變化。

從上面這個分析過程中可以得出,只需要一個緩存就能解決循環(huán)依賴了,那么為什么Spring中還需要singletonFactories呢?


5.2、Spring為什么需要三級緩存(singletonFactories)呢?

基于上面的場景想一個問題:

如果A的原始對象注入給B的屬性之后,A的原始對象進行了AOP產(chǎn)生了一個代理對象,

此時就會出現(xiàn),對于A而言,它的Bean對象其實應該是AOP之后的代理對象,而B的a屬性對應的并不是AOP之后的代理對象,這就產(chǎn)生了沖突。

大概是這么個過程

創(chuàng)建A-》填充B-》創(chuàng)建B-》填充A-》從singletonFactories獲取A-》B生命周期結(jié)束-》A初始化前和初始化-》進行AOP-》A放入單例池

經(jīng)過上面的步驟后

B依賴的A和最終的A不是同一個對象。


5.3、Spring是如何解決循環(huán)依賴的

下面這個方法是在填充屬性之前,會進行addSingletonFactory(beanName, () ->getEarlyBeanReference(beanName, mbd, 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");
			}
			addSingletonFactory(beanName, () ->getEarlyBeanReference(beanName, mbd, bean));
		}

其實就是把當前類A對象緩存到這個三級緩存里,因為這個對象如果實現(xiàn)了AOP,在后續(xù)他會從一個原始對象變成一個aop對象,所以采用了函數(shù)式接口,getEarlyBeanReference就是處理到底返回原始對象還是AOP的代理對象。

singletonFactories(三級緩存)中存的是某個beanName對應的ObjectFactory,在bean的生命周期中,生成完原始對象之后,就會構(gòu)造一個ObjectFactory存入singletonFactories中。

這個ObjectFactory是一個函數(shù)式接口,所以支持Lambda表達式:() ->getEarlyBeanReference(beanName, mbd, bean)

上面的Lambda表達式就是一個ObjectFactory,執(zhí)行該Lambda表達式就會去執(zhí)行getEarlyBeanReference方法,而該方法如下:

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {Object exposedObject = bean;
 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
   }
  }
 }
 return exposedObject;
}

該方法會去執(zhí)行SmartInstantiationAwareBeanPostProcessor中的getEarlyBeanReference方法,而這個接口下的實現(xiàn)類中只有兩個類實現(xiàn)了這個方法,一個是AbstractAutoProxyCreator,一個是InstantiationAwareBeanPostProcessorAdapter,它的實現(xiàn)如下:

InstantiationAwareBeanPostProcessorAdapter的實現(xiàn)

@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {return bean;
}

AbstractAutoProxyCreator的實現(xiàn)

@Override
public Object getEarlyBeanReference(Object bean, String beanName) {Object cacheKey = getCacheKey(bean.getClass(), beanName);
 this.earlyProxyReferences.put(cacheKey, bean);
 return wrapIfNecessary(bean, beanName, cacheKey);
}

該方法主要做了幾件事情

1、首先得到一個cachekey,cachekey就是beanName。

2、然后把beanName和bean(這是原始對象)存入earlyProxyReferences中

3、調(diào)用wrapIfNecessary進行AOP,得到一個代理對象。

在整個Spring中,默認就只有AbstractAutoProxyCreator真正意義上實現(xiàn)了getEarlyBeanReference方法,而該類就是用來進行AOP的。

前面提到的AnnotationAwareAspectJAutoProxyCreator的父類就是AbstractAutoProxyCreator。


5.4、什么時候會調(diào)用getEarlyBeanReference方法呢?

只有當出現(xiàn)了循環(huán)依賴的場景時才會去調(diào)用?為什么

如果調(diào)用的是C或者其他bean,其他bean并沒有和他循環(huán)依賴,這個時候getbean的時候 是可以從一級緩存里拿到的,

只有因為此時出現(xiàn)了循環(huán)依賴,A對象還沒有走完bean生命周期的,所以一級緩存里拿不到。

先想想現(xiàn)在的場景
1、A實例化-》添加三級緩存-》屬性填充B

2.1、B去創(chuàng)建對象,實例化
2.2、B添加三級緩存
2.3、屬性填充A(此時A的生命周期還沒有走完)-》一級緩存-》二級緩存-》三級緩存-》存到二級緩存
2.4、剩下的生命周期流程...

2、AOP(這里還有個問題需要處理,就是前面A已經(jīng)執(zhí)行了lamdba表達式,生成了AOP代理對象,這里無需再次執(zhí)行AOP)
3、A的剩下生命周期流程…


1、支持循環(huán)依賴的情況下,就會提前增加三級緩存*()

addSingletonFactory(beanName, () ->getEarlyBeanReference(beanName, mbd, bean));

2、在屬性填充時,每個填充的對象,都會先調(diào)用getBean,而getBean則會先調(diào)用getSingleton()方法

Object sharedInstance = getSingleton(beanName);

而在這個方法里面就會看到調(diào)用getEarlyBeanReference方法的地方

下面這個方法主要就是判斷一級緩存和二級緩存都不存在的情況下,根據(jù)beanName獲取三級緩存

調(diào)用singletonFactory.getObject()方法,他底層就是調(diào)用前面的lamdbabia表達式方法,生成原始或者代理對象,放到二級緩存,刪除掉三級緩存

解決循環(huán)依賴源碼的最新核心方法

protected Object getSingleton(String beanName, boolean allowEarlyReference) {// Quick check for existing instance without full singleton lock
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {	singletonObject = this.earlySingletonObjects.get(beanName);
			if (singletonObject == null && allowEarlyReference) {		synchronized (this.singletonObjects) {// Consistent creation of early reference within full singleton lock
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {singletonObject = this.earlySingletonObjects.get(beanName);
						if (singletonObject == null) {	ObjectFactorysingletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {		// 調(diào)用getEarlyBeanReference方法的地方
								singletonObject = singletonFactory.getObject();
								// 添加二級緩存
								this.earlySingletonObjects.put(beanName, singletonObject);
								// 刪除三級緩存
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}

注意這里還有個需要注意的點,在執(zhí)行這個方法時,會緩存當前bean到earlyProxyReferences里,他主要是用來標記這個bean是否進行過aop

@Override
	public Object getEarlyBeanReference(Object bean, String beanName) {Object cacheKey = getCacheKey(bean.getClass(), beanName);
		this.earlyProxyReferences.put(cacheKey, bean);
		return wrapIfNecessary(bean, beanName, cacheKey);
	}

初始化后部分源碼

可以看到他會先判斷earlyProxyReferences是否存在,以此來判斷是否進行過了aop

@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {if (bean != null) {	Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {		return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

通過上面代碼可以看到,如果提前進行過aop,他是直接返回了原始對象,并沒有緩存到單例池


5.5、如果提前進行了AOP,什么時候把AOP的代理對象放到單例池呢?

答案是初始化后,回去處理,源碼如下

如果進行了循環(huán)依賴,肯定會進下面的if

會再次獲取下當前bean,然后判斷傳當前bean和初始化后的bean是否相等,是的話,就證明是同一個原始對象,就把剛從二級緩存取到的代理對象進行賦值,并且最終返回

if (earlySingletonExposure) {	Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {		if (exposedObject == bean) {exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);
					SetactualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {	actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

六、三級緩存總結(jié) 6.1、singletonObjects(一級緩存)

作用:不論是spring源碼還是工作中經(jīng)常用到getBean(),都是從這個緩存單例池拿對象

值從哪里來的?經(jīng)歷了完整的聲明周期會存放進來

緩存經(jīng)過了完整生命周期的bean


6.2、earlySingletonObjects(二級緩存)

作用:他主要是解決在循環(huán)依賴過程中,保持對象的單例。

值從哪里來的?三級緩存執(zhí)行了lambda表達式后,生成的對象會放入二級緩存

原理解析
緩存未經(jīng)過完整生命周期的bean,

如果某個bean出現(xiàn)了循環(huán)依賴,就會提前把這個暫時未經(jīng)過完整生命周期的bean放入earlySingletonObjects中,

這個bean如果要經(jīng)過AOP,那么就會把代理對象放入earlySingletonObjects中,

否則就是把原始對象放入earlySingletonObjects,

但是不管怎么樣,就是是代理對象,代理對象所代理的原始對象也是沒有經(jīng)過完整生命周期的,所以放入earlySingletonObjects我們就可以統(tǒng)一認為是未經(jīng)過完整生命周期的bean。


6.3、singletonFactories(三級緩存)

作用:打破循環(huán)依賴的關鍵!

值從哪里來的?實例化后,存放

原理解析
緩存的是一個ObjectFactory,也就是一個Lambda表達式。

1、在每個Bean的生成過程中,經(jīng)過實例化得到一個原始對象后,都會提前基于原始對象暴露一個Lambda表達式,并保存到三級緩存中,

2、這個Lambda表達式可能用到,也可能用不到,如果當前Bean沒有出現(xiàn)循環(huán)依賴,那么這個Lambda表達式?jīng)]用,

當前bean按照自己的生命周期正常執(zhí)行,執(zhí)行完后直接把當前bean放入singletonObjects中,

3、如果當前bean在依賴注入時發(fā)現(xiàn)出現(xiàn)了循環(huán)依賴(當前正在創(chuàng)建的bean被其他bean依賴了),

3.1、則從三級緩存中拿到Lambda表達式,并執(zhí)行Lambda表達式得到一個對象,并把得到的對象放入二級緩存

3.2、如果當前Bean**需要AOP,**那么執(zhí)行l(wèi)ambda表達式,得到就是對應的代理對象,

3.3.、如果無需AOP,則直接得到一個原始對象。


6.4、earlyProxyReferences(是否進行了AOP緩存)

其實還要一個緩存,就是earlyProxyReferences,它用來記錄某個原始對象是否進行過AOP了。


七、什么場景下spring循環(huán)依賴不行 7.1、循環(huán)依賴的2個類都為原型Bean

原因:單例可以是因為有單例池,可以找到單例bean,原型Bean則沒辦法像單例那樣處理

如果只有有一個是單例的,就可以解決,無非就是多循環(huán)幾圈


7.2、構(gòu)造方法注入

原因:構(gòu)造方法寫死了依賴其他對象,這時根本無法創(chuàng)建實例


7.3、如何處理構(gòu)造方法注入解決?

@Lazy注解即可

原因:是因為,他會生成一個代理對象,可以規(guī)避掉無法創(chuàng)建實例的問題。


八、spring只用二級循環(huán)能否解決循環(huán)依賴問題?

先反向分析一下singletonFactories

8.1、為什么需要singletonFactories?

假設沒有singletonFactories,只有earlySingletonObjects,earlySingletonObjects是二級緩存,它內(nèi)部存儲的是為經(jīng)過完整生命周期的bean對象,Spring原有的流程是出現(xiàn)了循環(huán)依賴的情況下:

1、先從singletonFactories中拿到lambda表達式,這里肯定是能拿到的,因為每個bean實例化之后,依賴注入之前,就會生成一個lambda表示放入singletonFactories中

2、執(zhí)行l(wèi)ambda表達式,得到結(jié)果,將結(jié)果放入earlySingletonObjects中
?


8.2、那如果沒有singletonFactories,該如何把原始對象或AOP之后的代理對象放入earlySingletonObjects中呢?何時放入呢?

?

首先,將原始對象或AOP之后的代理對象放入earlySingletonObjects中的有兩種:

1、實例化之后,依賴注入之前:如果是這樣,那么對于每個bean而言,都是在依賴注入之前會去進行AOP,這是不符合bean生命周期步驟的設計的。

2、真正發(fā)現(xiàn)某個bean出現(xiàn)了循環(huán)依賴時:

按現(xiàn)在Spring源碼的流程來說,就是getSingleton(String beanName, boolean allowEarlyReference)中,是在這個方法中判斷出來了當前獲取的這個bean在創(chuàng)建中,就表示獲取的這個bean出現(xiàn)了循環(huán)依賴,

那在這個方法中該如何拿到原始對象呢?

更加重要的是,該如何拿到AOP之后的代理對象呢?

難道在這個方法中去循環(huán)調(diào)用BeanPostProcessor的初始化后的方法嗎?不是做不到,不太合適,代碼太丑。

最關鍵的是在這個方法中該如何拿到原始對象呢?

還是得需要一個Map,預先把這個Bean實例化后的對象存在這個Map中,那這樣的話還不如直接用第一種方案,但是第一種又直接打破了Bean生命周期的設計。
?

所以,我們可以發(fā)現(xiàn),現(xiàn)在Spring所用的singletonFactories,為了調(diào)和不同的情況,

在singletonFactories中存的是lambda表達式,這樣的話,只有在出現(xiàn)了循環(huán)依賴的情況,才會執(zhí)行l(wèi)ambda表達式,才會進行AOP,

也就說只有在出現(xiàn)了循環(huán)依賴的情況下才會打破Bean生命周期的設計,如果一個Bean沒有出現(xiàn)循環(huán)依賴,那么它還是遵守了Bean的生命周期的設計的。


九、循環(huán)依賴流程圖

在這里插入圖片描述

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

新聞名稱:Spring循環(huán)依賴源碼解析(深度理解)-創(chuàng)新互聯(lián)
網(wǎng)頁鏈接:http://vcdvsql.cn/article34/pjjse.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化關鍵詞優(yōu)化服務器托管軟件開發(fā)網(wǎng)站設計公司網(wǎng)站設計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)