转载

spring循环依赖简单描述

spring循环依赖是什么?

简单来说就是AB,两个类在相互依赖,那么在spring容器实例化,去创建A,B两个Bean的时候,到底先创建谁呢?先创建ABean,因为ABean中注入了BBean,那么就去先创建BBean,而BBean的创建又需要ABean,这样在创建的时候似乎陷入了一个”死循环“,那么spring是这么解决这个死循环的呢?注意,这里spring 仅仅是解决单例Bean的循环依赖,非单例模式spring是无法处理的。

@Component  
public class IndexService {  
  
  @Autowired  
  TestService testService;  
  
  public IndexService() {  
//        this.name = "xiaoming";  
  System.out.println("IndexService constructor");  
  
  }  
  
//    private String name ;  
//  
//    public void getIndex(){  
//        System.out.println("getIndex");  
//    }  
  
}

@Service  
public class TestService {  
  
  @Autowired  
  IndexService indexService;  
  
  public TestService() {  
  System.out.println("TestService constructor");  
  }  
}

现在我们一步步debug下

1.1

spring循环依赖简单描述

1.2

spring循环依赖简单描述

1.3

spring循环依赖简单描述

当debug到这里,indexService已经是跑完构造函数的object了。但是它还不是SpringBean,因为它还没有跑完Spring创建Bean的全部流程。图1.1中,红框的部分,在调用indexService构造函数,调用一些内置的BeanPostProcessor 之后,indexServic提前暴露了它的BeanFactory,可以看图1.3的代码,在这里方法中,indexService的factory已经被缓存了起来,这个factory可以理解我们再工厂中生产indexService的”模板“。在调用this.populateBean(beanName, mbd, instanceWrapper)就是我们给indexService填充它内部属性之前,我们先缓存一份它的”生产模板“,这个缓存就是spring 二级缓存,也是解决spring 循环依赖的关键。

2

spring循环依赖简单描述

我们继续debug,在this.populateBean(beanName, mbd, instanceWrapper)方法中,indexService需要填充testService属性,那我们就去单例池里面拿(spring所有创建成功的bean都会放在singletonObjects里面,这个称为单例池,也称为spring一级缓存),调用getSingleton(”testService“),发现没有,因为这个时候我们还没创建testService的Bean,既然我们在indexService中我们要引用了testService,结果没有,那么spring就去创建testService了,重新开始走创建testService的Bean的流程,

spring循环依赖简单描述

spring循环依赖简单描述

spring循环依赖简单描述

看图2.1,又走到了这里,这里同样的方法我们循环了一遍,同样先产生testSeriveBean的object,在填充属性前,在spring二级缓存中存下了testService的”生成模板“即singleFactory。然后填充testService属性的时候,发现我们需要indexService,回看1.1,1.2,1.3三幅debug截图,记住这个时候indexService还不是一个springBean,只是一个object,inddexService的创建流程只跑了一半,indexService是一个earlySingleton。

然后我们继续看,既然testService需要填充indexService,那我们就去拿吧。看图2.2,照样我们也先去调用getSingleton(”indexService“),注意这个时候getSingle("indexService")是有返回的!!可以看下2.3图中的简单逻辑,直接从singletonObejcts中拿indexService肯定没有,因为indexService还只是一个object,而且indexService正在创建中,那么我们就用之前缓存的indexService的singleFatory去创建一个indexService的earlySingleton,而且看2.3图,这里我们得到的indexServic的确是个”早产儿“或者说”半成品“。但是我们可以拿来填充我们的testService了!!!这样我们的testServicBean能顺利被spring生产出来。

spring循环依赖简单描述

这样testServiceBean能先顺利产生,那么我们要创建的indexServiceBean最后也顺利生产出来了。到此,spring借助singletonFactory(Map)二级缓存,解决了单例之前循环依赖的问题。

* 总结图:

黑线部分是spring循环依赖的循环逻辑,红线部分是spring打破这个死循环的大致设计原理。 *

spring循环依赖简单描述

~~~~

原文  https://segmentfault.com/a/1190000021349197
正文到此结束
Loading...