spring循环依赖
什么是循环依赖
循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于A。
spring设计三级缓存的意义,一二级缓存有什么意义?
bean在容器中默认是单列的,但是在同一个map中,如果半成品和成品放置了一起,有可能会get到半成品的对象,所以需要对map分层
一级缓存:成品对象
二级缓存:半成品对象
为什么还要设置三级缓存?
如果程序中用到了AOP则,必须要用到三级缓存,主要解决AOP的循环依赖问题
- aop过程干了什么?
生成了代理对象,代理对象不能原始对象同名
2.代理对象什么时候创建的?
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
// 提前暴露的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;
}
三级缓存:
主要从spring容器缓存中getSingleton
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);
}
总结:
当A.B俩类产生循环依赖的时候,spring容器会先从缓存中获取单列的bean对象,如果缓存中有beanName这个bean对象,则直接返回,如果没有则进行creatBean,并将A对象put进三级缓存中。进行属性B的填充,当容器中没有B对象,也是先进行creatBean对象,并将B对象put进三级缓存中,之后populateBean属性填充,因为之前A对象已经放在了三级缓存当中(k:beanName,V:()→getEarlyBeanReference),所以直接从三级缓存get
A对象,并将他放置在二级缓存中,将三级缓存中A引用地址清除,这时候二级缓存中的A对象为半成品对象,即就是只有实例化,没初始化。这时候B对象初始化完成,将完成品的B对象放置在一级缓存中,将三级缓存中的B引用地址清除,循环递归回溯,A对象就可以拿到B对象的实例,进行A对象的初始化,将A放置在一级缓存中。清除二级缓存的半成品A对象。
流程图: