【图灵周瑜老师Spring源码全集】依赖注入、Spring Beans、Spri
2023-09-02 18:22 作者:bilibili00007 | 我要投稿


循环依赖

三级缓存

proxy代理类,先执行切面逻辑再执行目标类原有的方法

- autowired 是setting注入吗?构造注入是设置普通对象还是代理对象?
- 正常应该是把代理对象放到单例池,而不是把普通的对象放到单例池。

- 需要判断是否有循环依赖,如果出现循环依赖就要在第一步做AOP,把代理对象放到单例池。
- 构造注入会导致循环依赖吗?

- creatingSet保存正在创建中的对象,2.2填充属性的时候如果没有在单例池(一级缓存)中找到,
- 则到creatingSet查找,如果有找到,则是存在循环依赖
- 出现循环依赖,则进行AOP创建代理对象

- 为了避免多次循环依赖,多次AOP导致重复创建,所以在2.2创建的代理对象需要放到二级缓存(earlySingletonObjects)起来。
- 单例池singletonObjects(一级缓存):经过bean的完整生命周期创建的bean保存的对象。

- 三级缓存singletonFactories作用是打破循环依赖,用于生成依赖对象的代理对象。

- 保存的是lambda表达式用于判断循环依赖并生成解决循环依赖的代理对象。

- 三级缓存生成代理对象后保存到earlySingletonObjects二级缓存

- 三级缓存中的lambda表达式执行完就会remove,因为已经产生了代理对象保存到二级缓存所以没有必要再保留

- 正常进行AOP的逻辑会判断是否已经有代理对象,如果已经有代理对象则不会进行AOP

- 构造注入导致的循环依赖Spring是无法解决的

- 需要增加无参构造方法,避免使用有参构造方法实例化
- lazy懒加载也可以解决。直接根据依赖的类生成代理对象,代理对象的生成方式跟之前不一样,这里生成的代理对象不会有目标对象。