这篇首先会介绍下解决循环依赖问题的三个类,然后再以一个例子来解释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()执行完