Spring 中循環依賴問題

在這裏插入圖片描述

測試

public class TestBean implements InitializingBean, BeanNameAware {


	private ItBean itBean;

	/**
	 * 構造函數
	 */
	public TestBean(){
		System.err.println("TestBean 構造器...");
	}


	public ItBean getItBean() {
		return itBean;
	}

	public void setItBean(ItBean itBean) {
		this.itBean = itBean;
	}

	/**
	 * InitializingBean 接口實現
	 */
	@Override
	public void afterPropertiesSet() throws Exception {
		System.err.println("TestBean afterPropertiesSet...");
	}


	public void print() {
		System.err.println("print方法業務邏輯執行");
	}

	@Override
	public void setBeanName(String name) {
		System.err.println("TestBean BeanNameAware...");
	}
}
public class ItBean {

	private TestBean testBean;

	public TestBean getTestBean() {
		return testBean;
	}

	public void setTestBean(TestBean testBean) {
		this.testBean = testBean;
	}

	/**
	 * 構造函數
	 */
	public ItBean(){
		System.out.println("ItBean 構造器...");
	}
}


xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="testBean" class="com.liu.cyclic.bean.TestBean">
		<property name="itBean" ref="itBean"/>
	</bean>

	<bean id="itBean" class="com.liu.cyclic.bean.ItBean">
		<property name="testBean" ref="testBean"/>
	</bean>
</beans>

TestBean依賴ItBean,而ItBean又依賴TestBean

原理圖

在這裏插入圖片描述

源碼

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
首先調用TestBean的無參構造方法,創建一個對象,只的創建對象並沒有設置屬性之類的.
在這裏插入圖片描述


protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//創建Bean 調用無參數構造方法,沒有屬性賦值
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
	...

放入三級緩存中

在這裏插入圖片描述

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
...

	/**
		 * 緩存中判斷是否需要提前暴露,
		 */
		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		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");
			}
			//加入3級緩存
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

addSingletonFactory
在這裏插入圖片描述

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

向下執行設置屬性

Object exposedObject = bean;
		try {
			/**
			 * 設置屬性
			 */
			populateBean(beanName, mbd, instanceWrapper);
			/**
			 * 調用初始化方法 Aware接口的方法init-method等 BeanPostProcessor方法
			 */
			exposedObject = initializeBean(beanName, exposedObject, mbd);

populateBean方法

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
...
		if (pvs != null) {
		//設置屬性
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

applyPropertyValues方法

在這裏插入圖片描述


protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
	...
else {
				String propertyName = pv.getName();
				Object originalValue = pv.getValue();
				//判斷是否必要的,這裏進入第二個Bean的實例化流程
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
				Object convertedValue = resolvedValue;


org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveValueIfNecessary

在這裏插入圖片描述
在這裏插入圖片描述


public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
		// We must check each value to see whether it requires a runtime reference
		// to another bean to be resolved.
		if (value instanceof RuntimeBeanReference) {
			RuntimeBeanReference ref = (RuntimeBeanReference) value;
			return resolveReference(argName, ref);
		}

org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveReference


@Nullable
	private Object resolveReference(Object argName, RuntimeBeanReference ref) {
		try {
			Object bean;
			String refName = ref.getBeanName();
			refName = String.valueOf(doEvaluate(refName));
			if (ref.isToParent()) {
				if (this.beanFactory.getParentBeanFactory() == null) {
					throw new BeanCreationException(
							this.beanDefinition.getResourceDescription(), this.beanName,
							"Can't resolve reference to bean '" + refName +
									"' in parent factory: no parent factory available");
				}
				bean = this.beanFactory.getParentBeanFactory().getBean(refName);
			}
			else {
				//從工廠中獲取Bean再從進入doGetBean
				bean = this.beanFactory.getBean(refName);
				this.beanFactory.registerDependentBean(refName, this.beanName);
			}
			if (bean instanceof NullBean) {
				bean = null;
			}
			return bean;
		}

再次進入org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean方法
這裏創建的是第二個對象
在這裏插入圖片描述
再向下調用createBean方法
在這裏插入圖片描述

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean方法

在這裏插入圖片描述

創建了ItBean使用無參構造,下面再次放入三級緩存中,再進入設置屬性
在這裏插入圖片描述

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues方法中

else {
				String propertyName = pv.getName();// testBean
				Object originalValue = pv.getValue();
				//
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
				Object convertedValue = resolvedValue;

org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveReference

在這裏插入圖片描述

再次

在這裏插入圖片描述

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

在這裏插入圖片描述
返回到 org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveReference
在這裏插入圖片描述
再註冊第二個Bean

再返回org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveValueIfNecessary

一直回到 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

在這裏插入圖片描述
完成第二個Bean的實例化,

回到第一個Bean的流程中

org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveReference
在這裏插入圖片描述

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean


		/**
		 * 獲取單例對象 嘗試去緩存中獲取
		 */
		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);
```
##### 返回 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200630171645886.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tvMDQ5MQ==,size_16,color_FFFFFF,t_70)
完成對象實例化
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章