随堂笔记8-spring循环依赖
### spring循环依赖
// A依赖了B
class A{
public B b;
}
// B依赖了A
class B{
public A a;
}
以上就会出现循环依赖,解决方法,二级三级缓存
-
bean的生命周期:
- spring扫描class文件生成beanDefinition
- 根据得到的beanDefinition生成bean
- 根据class推断构造方法
- 填充属性(依赖注入)
- 如果某个对象被aop则要生成代理对象
- 把最终的代理对象放入单例池中,下次获取bean时直接从单例池中获取
-
三级缓存
- 一级缓存 singletonObjects ;里面的bean对象经历了完整的生命周期
- 二级缓存 earlySingletonObjects ;是早前的bean对象
- 三级缓存 singletonFactories; 是创建早期bean对象的工厂
-
如何打破循环依赖
- 通过缓存解决,但是存在问题,这个放入缓存中的是原始对象还是代理对象,这个可能导致b依赖a产生冲突
-
三级缓存 singletonFactories
- 首先在bean的生命周期内会构造一个objectFactory存入singletonFactories中,这是一个函数接口,为了创建aop代理对象,如果执行这个则会吧代理对象放入 earlySingletonObjects
- 此时对于a而言,当b创建完后,a继续执行生命周期,按照他本身逻辑进行aop,此时会判断当前beanName是否在earlyProxyRefenrences中。经过aop判断后要把a对应的对象放入singletonObjects中,要放入的是代理对象,所以会从earlySingletonObjects中取。至此循环依赖结束
- 注意 earlyProxyReferences 这也是一个缓存,记录原始对象是否进行了aop
-
为什么一定要三级缓存
- 我的理解,为了遵守bean的生命周期设计
- 不知何时吧aop代理对象或者原始对象放入earluSingletonObjects中
不恋尘世浮华,不写红尘纷扰
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理