Spring循环依赖

ABA问题 ,出现循环依赖

 SpringBean生命周期主要5个阶段

1. 实例化对象

2. 属性赋值(值的来源是DI

3. 初始化 (初始化完成就是个Bean)

4. 使用

5. 销毁

Spring扫描到被 @Service 标记的A类后,会创建A对象,A类里的有B对象,那么就说A依赖了B;

因为B上被 @Autowired 标记,Spring又会去解析这个 @Autowired注解,表明需要为b赋值,Spring先试着从缓存获取Bbean,如果缓存有就不会进入SpringBean生命周期,直接返回Bbean并赋予A的属性b,没有就要创建Bbean再赋值给b,这个过程称为依赖注入

A在推断构造完成了A 对象实例化,此时的b=null, 意味b对象里面的方法是不能被调用的,报空指针,A属性赋值都没走完,自然也没有完成初始化,所以我愿称此时A为不完整、不成熟的普通对象,总之A不是Bean。A不成熟不代表属于A的方法不能被使用呀,它只是一个属性 b=null而已,A内部其它不依赖b的方法还是可以的,所以将A放入一个临时X缓存慢慢发育。紧接着进入 属性赋值 阶段

假设Spring没有从缓存中获取Bbean,就会进入依赖注入(DI)创建Bbean,

1.实例化B

2.属性赋值 ----> 取出X缓存中 不成熟的A普通对象 (不成熟,不代表不可用,Spring的循环依赖的理论依据基于Java的引用传递,当获得对象的引用时,对象的属性是可以延后设置的

3.初始化  

因为B能走到初始化阶段,意味b能称为Bean,

好了问题来了Bbean要缓存在哪里?????? 

结论: 如果想打破死循环,使用一级缓存就可以,如上图缓存X,红色表示成熟的Bean与早期态Bean共存,坏处就是红色小字,后面新开辟一块缓存装成熟态的Bean,以后使用从Y缓存获取bean就好,貌似很好解决问题了,但是Spring其实使用的3级缓存,为什么?

先弄清楚3级缓存分别存的是什么?

1. 一级缓存(SingletonObjects):成熟态,完整的Bean

2.二级缓存(EarlySingletonObjects):早期态的实例  (解决:重复创建aop-proxy问题)

3. 三级缓存(SingletonFactory):lambda(beanName,Object)函数接口

所以缓存的访问顺序:先132后12

看到上面的步骤,我还是有点不死心,还是想干掉第三级缓存,A不是要aop创建代理对象嘛!我在B依赖注入(属性赋值)时就创建aop动态代理不就好了,是可以,但是不符合spring的生命周期规范,动态代理是在初始化阶段进行的,初始化阶段有个BeanPostProcessor扩展接口

  • 29
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值