天天看點

spring源碼學習總結9-IOC-循環依賴問題解決

這篇首先會介紹下解決循環依賴問題的三個類,然後再以一個例子來解釋spring是怎麼解決循環依賴的

一、DefaultSingletonBeanRegistry

介紹:spring解決循環依賴的核心類,用來存放三級緩存

變量 :

/** 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);

	/** Set of registered singletons, containing the bean names in registration order */
	private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);
           

一級緩存:beanName->bean執行個體,緩存初始化後的bean對象 :

Map<String, Object> singletonObjects

= new ConcurrentHashMap<>(256)

二級緩存:beanName->bean執行個體,緩存提前拿原始對象進行AOP後得到的代理對象 :

Map<String, Object> earlySingletonObjects

= new HashMap<>(16)

三級緩存:beanName->ObjectFactory,緩存對象工廠,用來建立某個對象 :

Map<String, ObjectFactory<?>> singletonFactories

= new HashMap<>(16)

方法:

addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) 方法:

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

作用:将singletonFactory存入三級緩存

Object getSingleton(String beanName, boolean allowEarlyReference) 方法:

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

方法内容

1.從一級緩存在中取,this.singletonObjects.get(beanName),取不到

1.從二級緩存在中取,this.earlySingletonObjects.get(beanName),還取不到

3.從三級緩存在中取,this.singletonFactories.get(beanName)

4.singletonFactory不為空 :

獲得bean執行個體:singletonFactory.getObject()

将其放入二級緩存:this.earlySingletonObjects.put(beanName, singletonObject)

将其從三級緩存去除:this.singletonFactories.remove(beanName)

addSingleton(String beanName, Object singletonObject) 方法:

protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}
           

方法内容

1.将bean放入一級緩存:this.singletonObjects.put(beanName, singletonObject)

2.将bean從二級緩存删除:this.earlySingletonObjects.remove(beanName)

3.将bean從三級緩存删除:this.earlySingletonObjects.remove(beanName)

二、AbstractAutoProxyCreator

介紹:springAOP的核心類,用來建立代理對象

變量

Map<Object Object> earlyProxyReferences

:

标記Object是否進行過代理,執行過BeanPostProcess方法

方法

getEarlyBeanReference()方法

方法内容:

1.this.earlyProxyReferences.put(cacheKey bean) :

标記Object進行過代理

2.

wrapIfNecessary(bean beanName cacheKey) :

周遊攔截器,如果比對advice建立代理(内容很長,是springAOP的核心内容,後續再詳細介紹) ,比對不到,就傳回原來的bean

postProcessAfterInitialization()方法

判斷this.earlyProxyReferences是否存在bean,存在删除并傳回

不存在,執行

wrapIfNecessary(bean beanName cacheKey)

方法

三、ObjectFactory

介紹:類似FactoryBean

方法

T getObject()

四、舉例介紹

假設現在A依賴于B,B依賴于A

不熟悉getBean(),doCreateBean()方法内容的,看前一章,不然可能會思路跟不上

這裡也重複下前一節的doCreateBean()方法

方法内容(4部分)

如下:

1.執行個體化Bean對象:

createBeanInstance()

2.将bean放入singletonFactories中(一個map) ,key為beanName ,value類型為AbstractAutowireCapableBeanFactory

addSingletonFactory(beanName, new ObjectFactory() {

@Override

public Object getObject() throws BeansException {

return getEarlyBeanReference(beanName, mbd, bean);

}

});

3.依賴注入:

populateBean()

4.回調方法:

initializeBean()

現在開始初始化A

spring源碼學習總結9-IOC-循環依賴問題解決

1.A初始化 :

使用反射生成原始Bean

将A的原始Bean放入singletonFactories中(一個map),key為beanName value類型為AbstractAutowireCapableBeanFactory

2.A開始依賴注入:

populateBean()方法 内部調用getBean()擷取B

3.B開始初始化 使用反射生成原始Bean

4.B依賴注入 :

發現B依賴A,getBean()擷取A

protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);
		.....
	}
           

5.從緩存中取出A執行個體

@Override
	public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);
	}
	
	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);
	}
           

内容:

1.去singleton緩存中找執行個體 發現A的bean存在于singletonFactories中 根據beanName得到一個ObjectFactory

2.執行ObjectFactory.getObject()方法,得到一個A原始對象經過AOP之後的代理對象(也可能沒有比對advisor,還是傳回執行個體的bean)

6.從三級緩存放入二級緩存,并清空三級緩存

内容:

1.将bean生成的代理放入二級緩存earlySingletonObjects中(一個map) key為beanName,value為bean

2.将bean從三級緩存singletonFactories中清空:this.singletonFactories.remove(beanName);
           

B初始化完成

7.A繼續初始化:

initializeBean() :

執行AbstractAutoProxyCreator的postProcessAfterInitialization方法

判斷目前beanName是否在earlyProxyReferences

如在:已經提前進行過AOP比對,無需再次進行AOP比對

如不在:進行BeanPostProcessor的相關操作

8.将A執行個體放入一級緩存singletonObjects中,清空二級緩存與三級緩存

protected <T> T doGetBean(
		final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
		throws BeansException {
	...
	// Create bean instance.
	if (mbd.isSingleton()) {
		sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
			@Override
			public Object getObject() throws BeansException {
				try {
					return createBean(beanName, mbd, args);
				}
				catch (BeansException ex) {
					// Explicitly remove instance from singleton cache: It might have been put there
					// eagerly by the creation process, to allow for circular reference resolution.
					// Also remove any beans that received a temporary reference to the bean.
					destroySingleton(beanName);
					throw ex;
				}
			}
		});
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
	}
	...
	return (T) bean;
}
           

getSingleton(),為

DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
	Object singletonObject = this.singletonObjects.get(beanName);
	if (singletonObject == null) {
		if (this.singletonsCurrentlyInDestruction) {
			throw new BeanCreationNotAllowedException(beanName,
					"Singleton bean creation not allowed while singletons of this factory are in destruction " +
					"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
		}
		if (logger.isDebugEnabled()) {
			logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
		}
		beforeSingletonCreation(beanName);
		boolean newSingleton = false;
		boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
		if (recordSuppressedExceptions) {
			this.suppressedExceptions = new LinkedHashSet<Exception>();
		}
		try {
			singletonObject = singletonFactory.getObject();
			newSingleton = true;
		}
		catch (IllegalStateException ex) {
			// Has the singleton object implicitly appeared in the meantime ->
			// if yes, proceed with it since the exception indicates that state.
			singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				throw ex;
			}
		}
		catch (BeanCreationException ex) {
			if (recordSuppressedExceptions) {
				for (Exception suppressedException : this.suppressedExceptions) {
					ex.addRelatedCause(suppressedException);
				}
			}
			throw ex;
		}
		finally {
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = null;
			}
			afterSingletonCreation(beanName);
		}
		if (newSingleton) {
			addSingleton(beanName, singletonObject);
		}
	}
	return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
           

A初始化完成

五、總結下解決循環依賴的三段核心代碼:

1.addSingletonFactory(beanName () -> getEarlyBeanReference(beanName mbd bean))

代碼所在類:

AbstractAutowireCapableBeanFactory

(繼承自DefaultSingletonBeanRegistry)

doCreateBean()

方法内代碼(AbstractAutowireCapableBeanFactory類)

方法調用節點:bean反射建立執行個體,依賴注入前

2.Object sharedInstance = getSingleton(beanName) :

代碼實作類:

DefaultSingletonBeanRegistry

populateBean()->getBean()->doGetBean()方法内代碼(AbstractBeanFactory類)

方法調用節點:getBean()獲得執行個體,未到doCreateBean()

3.Object sharedInstance = getSingleton(beanName () -> createBean(beanName mbd args) ) :

代碼實作類:

DefaultSingletonBeanRegistry

populateBean()->getBean()->doGetBean()方法内代碼(AbstractBeanFactory類)

方法調用節點:getBean()獲得執行個體,doCreateBean()執行完

繼續閱讀