Spring循环依赖

1、Spring初始化bean的过程(bean的生命周期)

1. Spring扫描class文件得到beanDefinition
2. BeanDefinition首先根据class的构造方法反射得到一个对象(如果反射无法获取对象,则根据工厂方法生成)
3. 实现属性的依赖注入
4. 如果实现了BeanNameAware接口,调用setBeanName方法,为beanName赋值
5. 如果bean里有方法被切面增强了,则根绝原始对象生成一个代理对象
6. 最后将生成的代理对象放入singletonObjects缓存中,也就是Spring的一级缓存中(也叫单例池)

 2、三级缓存

一级:singletonObjects,存放经过完整生命周期的实例

二级:earlysingtonObjects,存放早期bean对象(生命周期进行中的对象)

三级:singletonFactories,对象工厂,一个lambda表达式,基于早期对象暴露的一个lambda表达式

3、循环依赖

在bean A的生命周期经过了反射得到具体对象之后,bean A依赖于bean B,这时会去初始化bean B实例,在初始化bean B之前,会将bean A放入二级缓存earlysingletonObjects中,并在singletonFactories里生成一个ObjectFactory,这个ObjectFactory是一个lambda表达式,可以通过表达式获取对相应的原始对象,然后在bean B初始化的时候,发现它依赖于bean A,这时getBean会调用singletonFactories的表达式获取earlysingtonObject缓存池中的原始对象,bean B生命周期结束,回到bean B,生命周期正常结束。

4、构造函数注入不能解决循环依赖的问题

bean A中通过构造函数依赖bean B,bean B中通过构造函数依赖bean A,在初始化A的时候,是在解析构造函数参数的时候去初始化bean B,这时当前的bean A还没完成实例化,连对象都还没生成,在初始化bean B的时候,在三级缓存里找不到这个bean A,又会去初始化bean A,这样就无限递归,最终都不能完成初始化。

posted @ 2024-02-16 14:57  leviH  阅读(9)  评论(0编辑  收藏  举报