spring目前只能解决属性中的循环依赖,构造方法中的没办法解决,会报异常,这个其实和spring解决循环依赖的机制有关 ,往下看其实就明白了。
实现:
Bird和Dog里面互相依赖对方,循环依赖
1、按照bean的创建流程走下去
doGetBean()
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 从singleton缓存对象中获取,能获得到直接返回
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
....
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
if (!typeCheckOnly) {
// 给一个标志位,其实是往一个map里面存对象
markBeanAsCreated(beanName);
}
try {
// 合并
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
getBean(dep);
}
}
// Create bean instance.
if (mbd.isSingleton()) {
// 单实例bean创建
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// 多例
}else {
// 自定义scope
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
return (T) bean;
}
getSingleton 从缓存中获取单实例bean
重要的点: 三级缓存
一级缓存: singletonObjects 存放完整的bean对象
二级缓存: earlySingletonObjects 存放半成品bean
三级缓存: singletonFactory 存放factory,持有bean内存引用,BeanPostProcessor处理
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// singletonObjects -> map 缓存中获取
Object singletonObject = this.singletonObjects.get(beanName);
// 缓存中为空,并且对象已经再创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 从earlySingletonObjects中获取 二级缓存
singletonObject = this.earlySingletonObjects.get(beanName);
// 二级缓存没有,走三级缓存 singletonFactory中获取
if (singletonObject == null && allowEarlyReference) {
// 这个factory会在创建bean的时候提前put进去
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// getObect 获取对象,放入二级缓存,删除三级缓存
// 删除三级缓存的目的,防止重复创建bean,创建后factory无用了
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
上面最终是从singletonFactory中取,放入三级缓存的逻辑在doCreateBean中实现
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
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;
}
创建bean:
先getSingleton的时候,beforeSingletonCreation(beanName);
设置bean 到 singletonsCurrentlyInCreation 创建中
ceateBean内部会设置三级缓存singletonFactory
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
怎么注入的逻辑,其实看populate方法,进行依赖注入时,后置处理器处理的逻辑即可,这个在IOC的博客其实有写
其实方法命名已经很规范了,处理property value pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
AutowiredAnnotationBeanPostProcessor
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 这里进行注入
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
autowire的调用栈:
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);beanFactory.getBean(beanName);
第一个bean Bird 在进行populate的时候,属性注入,需要取创建内部的bean Dog,继续创建。
Dog 创建bean,getSingleton() 时,还是返回null,继续往下populate ,autowaire注入时,发现需要bird,继续去getBean
这次getSingleton时,从三级缓存中获取到了,Bird注入到Dog,Dogbean创建完成以后,再返回bean给Bird,Bird创建完成,实现循环依赖注入
二级缓存和三级缓存的必要性
三级缓存的本质是factory,持有createBean时的bean引用,factory.getObject()的时候,会走beanPostProcessor,AOP等进行创建。
二级缓存存在的作用理解为,存放三级缓存创建的不完整对象
去掉三级缓存,则不能实现后置处理器的功能
去掉二级缓存,则会出现重复创建 bean对象的情况,不满足单例的特性