spring三级缓存

大家在实际使用spring的时候,不知道有没有发现,spring在实现依赖注入的时候,每一个被注入的对象必须有无参构造器。否则会提示你不能自动注入(如图)。

原因就是,spring在注入对象的时候,会先调用无参构造器创建一个空的对象,然后在调用对象的set方法一个个的进行属性值的传入。但是为什么spring会选择这种初始化方式而不是直接调用有参构造器进行对象创建呢,这就涉及到了spring的设计 -- 三级缓存。

首先假想一个场景嗷,如果有两个对象,A依赖B,B依赖A,在你的理解中spring能不能直接创建出这两个对象呢。为了解决这种循环依赖的问题,spring设计了一种初始化形式。还是上边这个栗子,spring首先要 new A对象,new 完的时候发现A还依赖着B,于是先将new好的空A对象放入二级缓存中,开始 new B对象,new完B对象进行属性值的set,然后发现需要setA,于是将缓存中的空A放入属性中,B对象就创建完毕放入一级缓存,A对象等到了创建完毕的B,然后将Bset进自己的属性,创建完毕后将自己也放入一级缓存,这样一个循环依赖的对象就创建完成了。

到这里是不是觉得二级缓存就能搞定循环依赖的问题了?是的,如果仅仅是循环以来的问题,二级缓存就能搞得定,但是spring想得更深一点,spring的aop等在使用的时候,会创建一个代理对象,这种代理对象的创建不能和实际使用的对象是两个对象啊,于是spring又加了一级缓存,用来存放创建对象的工厂类,从根源上解决了普通对象和代理对象不一致的问题,也形成了如今三级缓存的设计方式。

简单的小问题总结:

1、为什么使用构造器注入属性的时候不能解决循环依赖问题?

原因在于此方式是实例化和初始化分开(在进行实例化的时候不必给属性赋值)来操作,将提前实例化好的对象提前暴露出去,供别人调用,而使用构造器的时候,必须要调用构造方法了,没有构造方法无法完成对象的实例化操作,也就无法创建对象,那么永远会陷入到死循环中。

2、一级缓存能不能解决此问题?

不能,在三个级别的缓存中,放置的对象是有区别的,(1、是完成实例化且初始化的对象,2,是实例化但是未初始化的对象)如果只有一级缓存,就有

可能取到实例化但未初始化的对象,属性值都为空,肯定有问题

3、二级缓存能不能解决?为什么要三级缓存?

理论上来说是可以解决循环依赖的问题,但是要注意了:为什么要在三级缓存中放匿名内部类?本质在于为了创建代理对象,假如现在有A类,需要生成代理对象,A需不需要实例化,需要在三级缓存中放置的是,生成具体对象的一个匿名内部类,这个匿名内部类可能是代理类,也可能是普通的实例对象,而使用三级缓存就保证了不管是否需要代理对象,都保证使用的是一个对象,而不会出现前面使用普通bean,后面使用代理类的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摆烂的小趴菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值