循坏依赖指的是,A对象中持有B对象的引用,而B对象中持有A对象的引用,他们之间形成了循环依赖。或者是多个对象之间A依赖于B,B依赖于C,C又依赖A,形成循环依赖。又或者是对象自己依赖于自己。
在spring中实际上是使用三级缓存来解决循环依赖的,spring中的三级缓存分别是
private final MapsingletonObjects = new ConcurrentHashMap<>(256); private final Map earlySingletonObjects = new ConcurrentHashMap<>(16); private final Map > singletonFactories = new HashMap<>(16);
创建两个循环依赖的对象
@Component
public class A {
@Autowired
private B b;
}
@Component
public class B {
@Autowired
private A a;
}
spring中遇到循环依赖对象的创建步骤
1.在创建A对象时会先创建一个ObjectFactory工厂类
2.调用populateBean向A对象中注入属性
具体代码如下(AbstractAutowireCapableBeanFactory抽象类中的方法)
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
......
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//向第三级缓存中添加一个,ObjectFactory工厂类
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
try {
//向对象中注入属性
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
......
}
3.在注入属性时会在容器中寻找B对象但是没有找到B对象,则开始B对象的创建流程
4.在B对象的创建过程中同样会调用上面代码中的populateBean方法向B对象中A对象
5.这时候会调用getBean方法获取A对象
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
6.在获取A对象的时候会从缓存中尝试获取,这时候从三级缓存中可以获取到A对象的工厂
protectedT doGetBean( String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { String beanName = transformedBeanName(name); Object beanInstance; // 这个方法里面就会创建A对象并且放入第二级缓存中 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null); } ...... } protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { synchronized (this.singletonObjects) { singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { //获取到前面第一步中放入的ObjectFactory ObjectFactory> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { //创建A对象 singletonObject = singletonFactory.getObject(); //将A对象放入第二级缓存中 this.earlySingletonObjects.put(beanName, singletonObject); //将第三级缓存中的A对象的ObjectFactory移除 this.singletonFactories.remove(beanName); } } } } } } return singletonObject; }
以上就是spring中解决循环依赖的方法



