spring的三级缓存

问题引入

Spring的循环引用

有时候我们可能会涉及到两个bean对象互相引用的情况,通过对bean的实例化过程的了解,我们知道spring会先将这个bean对象所有的实例属性填充完毕,才会将这个bean实例化。于是这样便会产生一个死锁问题。对于这种情况,spring内部采用了三级缓存机制来解决上述问题。
举个例子

<!--循环引用-->


    <bean name="UserDao" class="com.cjh.dao.impl.UserDaoImpl">
        <property name="UserService" ref="UserService"></property>
    </bean>
    <bean name="UserService" class="com.cjh.service.impl.UserServiceImpl">
        <property name="UserDao" ref="UserDao"></property>
    </bean>

三级缓存


public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    //缓存最终单例bean成品的容器,即储存实例化和初始化都完成的bean,被称为一级缓存
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
    //早期Bean单例池,用于缓存已经被其他对象引用过的半成品对象,被称为二级缓存
    private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
    //单例Bean的工厂池,缓存未被引用的半成品对象,使用时通过工厂创建Bean,被称为三级缓存
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
    
    }

运用三级缓存解决循环依赖的过程

借用一下上面的UserService和UserDao互相依赖的例子。
因为我们的UserService配在UserDao的上面,我们会先加载UserService。
首先先实例化UserService,但是还未初始化,将其放入我们的三级缓存中。
之后我们为UserService注入属性,发现需要UserDao,到缓存中找,发现没有。
实例化UserDao,未完成初始化,将其放入三级缓存中。
UserDao进行属性注入,发现需要UserService,在三级缓存中找到,将其获取,并将其移入二级缓存
UserDao执行其他的生命周期过程,成为一个完整的bean,存到一级缓存,删除二三级缓存。
UserService注入UserDao
UserService执行其他的生命周期过程,成为一个完整的bean,删除二三级缓存。

三级缓存之所以要三级而不是两级

是因为我们的第三级缓存是一个objectfactory,工厂来创建bean。
如果你有两个对象都需要引用这个bean的话,如果没有二级缓存,那么三级缓存内部是会又重新创建了一个bean,
这显然是有问题的。

为什么要用ObjectFactory实例化Bean

是为了可以让我们的bean得到代理,实现功能的增强。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

风过于前

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

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

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

打赏作者

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

抵扣说明:

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

余额充值