這篇首先會介紹下解決循環依賴問題的三個類,然後再以一個例子來解釋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

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()執行完