【Spring源代码阅读之十二】spring的Bean创建过程和图解spring是如何解决循环依赖的

spring的Bean创建过程、spring是如何解决循环依赖的

  • 创建过程图
  • 循环依赖
    • 集合
    • 循环依赖代码
    • 话解
    • 图解

创建过程图

spring在容器的启动创建阶段,对单例Bean等会默认进行实例的创建,其实就是获取需要创建实例的BeanName,调用getBean方法对其进行创建,只不过就是没有接收返回的参数而已,只是为了Bean的实例化,因为在Bean实例化过程的最后将Bean实例已经放进了集合中了,当再次调用getBean时就直接从集合中获取了,不再执行创建代码了
【Spring源代码阅读之十二】spring的Bean创建过程和图解spring是如何解决循环依赖的_第1张图片

循环依赖

集合

spring对于循环依赖的处理就是使用了四个集合,包括:

  1. 实例正在创建流程中集合,实例创建流程前将BeanName放到该集合中,表示此Bean开始创建了。实例创建完成并且填充属性等流程处理后,BeanName从集合中移除,表示Bean实例创建完成
  2. 实例创建完成集合,当Bean实例通过反射使用spring推断的构造函数newInstance()创建实例后,将BeanName和实例放到集合中,此时Bean实例是原始Bean实例,可作为解决依赖的重要一环,因为这时Bean实例已经创建,但是属性没有填充,也就是没有解析依赖
  3. 发生循环依赖集合,当一个Bean的依赖链中有Bean又依赖了此Bean,这时就发生了循环依赖,spring这时会从第二步的集合中取出,第二步集合中放的是实例工厂对象,取出后调用获取方法,此方法会执行后置处理器,返回原始Bean实例,也有可能会返回的是代理,这样,循环依赖就解决了
  4. Bean实例集合,此集合中存放已经通过Bean实例创建流程创建好的实例,实例属性已经填充完,这个集合主要在Bean实例创建流程走之前,获取一下,不存在的话才进行创建流程,其实此集合对于循环依赖的解决没有发挥作用,但是这个集合也贯穿了整个流程,也可以算是一个处理集合吧

这几个集合,在Bean实例创建流程中在不同的时机对其进行增删操作,以此来解决循环依赖,同时spring可以调节可解决的循环依赖,有些循环依赖是spring处理不了的,例如原型模式Bean的循环依赖,因为原型Bean每次调用都是新实例,所以不能用集合来处理,这个就是不可调节的循环依赖

循环依赖代码

依赖关系是: demo依赖demo2,demo2依赖demo3,demo3依赖demo
这里的示例使用了三个类的循环依赖链,其实循环依赖链有两个类就可以,无论两个还是多个,原理是一样的
【Spring源代码阅读之十二】spring的Bean创建过程和图解spring是如何解决循环依赖的_第2张图片

DemoService

@Component
public class DemoService {

	@Autowired
	DemoService2 demoService2;
}

DemoService2

@Component
public class DemoService2 {

	@Autowired
	DemoService3 demoService3;
}

DemoService3

@Component
public class DemoService3 {

	@Autowired
	DemoService demoService;
}

话解

创建A实例,标识A正在创建中,创建实例(未填充属性),放进实例已创建集合,解析依赖 -> 创建B实例,标识B正在创建中,创建实例(未填充属性),放进实例已创建集合,解析依赖 -> 创建C实例,标识C正在创建中,创建实例(未填充属性),放进实例已创建集合,解析依赖 -> 依赖A,从实例已创建集合中取出 -> 实例C创建完成 ->实例B创建完成 ->实例A创建完成

图解

【Spring源代码阅读之十二】spring的Bean创建过程和图解spring是如何解决循环依赖的_第3张图片
图解中画的并不代表全部,有些对循环依赖解决关系不大的流程这里就没画出来

你可能感兴趣的:(spring源代码)