为什么会出现死循环?
因为bean的创建存在先后,创建beanA时依赖注入BeanB,但BeanB还没创建,我们就回去创建BeanB,但是BeanB又需要依赖注入BeanA,就会造成死循环。
二级缓存为什么不能解决问题?
实际上二级缓存就能解决问题,但是很多时候我们用到的不是真正的对象,而是代理类的对象,因为依赖注入先发送,创建代理对象后发生,此时用二级缓存Bean中注入的不是代理类对象,而是真正的对象,这样肯定不行,我们还指望用代理对象进行功能增强呢。
spring创建一个Bean的步骤:
以类A为例,我们创建类A的bean
1.判断一级缓存中是否存在beanA,存在直接返回,不用再创建了
2.创建一个半成品A对象,new A();
3.创建A的工厂对象放入三级缓存
4.依赖注入
5.创建A的代理对象
所以我们用到三级缓存
singletonObject:一级缓存,成品对象
earlySingletonObject:二级缓存,存放工厂生成出的产品对象(可能是半成品bean(),也可能是半成品代理bean )因为代理对象持有的真实对象是半成品所以叫半成品代理对象。
singletonFactories:三级缓存,存放实例化完成的 Bean 工厂
原理:
当获得对象的引用时,对象的属性是可以延迟设置的,我们先给出一个半成品对象。至少有地址。
1.当我们创建对象A时,先创建A的半成品对象,new A()–>创建A的工厂对象放入三级缓存–>依赖注入B
2.创建B的半成品对象,new B()–>创建B的工厂对象放入三级缓存–>依赖注入A
3.从三级缓存中找到A的工厂对象–>用得到的A的工厂对象创建出A的半成品对象或者代理对象(取决于A是否需要代理)放入二级缓存中,同时删除三级缓存中A的工厂对象
4.B创建成功->创建B的代理对象(如果需要代理的话),将b对象或b的代理对象放入一级缓存。
5.A对象创建成功–>创建A的代理对象(如果需要代理的话)–>从一级缓存,二级缓存中找,如果有直接拿来使用,将A或A的代理对象存入一级缓存。