Spring三级缓存

前言 :

Spring在进行属性注入时:
    注入普通属性时 : String int等存储基本类型的集合时,直接通过set方法的反射设置进去
    注入单向对象引用属性时 : 从当前容器中getBean    获取后通过set方法反射设置进去,如果当前容器没有, 则会先创建被注入对象bean实例(完成整个生命周期)后,在注入进当前bean。
    注入双向对象引用属性时 : 可以说循环依赖    涉及到三级缓存

三级缓存:

通过ClassPathxmlApplicationContext容器类中太祖宗类"DefaultSingletonBeanRegistry"中我们发现

singletonObjects            -- 单例池                      一级缓存        存储完整Bean
earlysingletonObjects    -- 早期Bean单例池       二级缓存        存储被引用的半成品Bean
singletonFactories         -- 单例Bean工厂池       三级缓存        存储未被引用的半成品Bean

这便是spring中的三级缓存

应用场景:

我们假设要往Spring容器中注入两个bean

<bean id="mapper" class="xxx">
        <property name="service" ref="service"></property>
    </bean>
<bean id="service" class="xxx">
        <property name="mapper" ref="mapper"></property>
</bean>

 在创建mapper需要注入service        创建service需要注入mapper 在没有三级缓存的情况下为

这就是通常我们说的循环依赖会直接造成死循环 

那么Spring是如何通过三级缓存解决这个问题的呢 现在就来我们来揭晓 , 通过翻阅源码我在这里简易的为大家解答

        还是针对于上方案例 : 

                假设先执行service的创建, 在service实体化为对象时 在堆内存中会开辟一个空间存储

                这个时的service还未被初始化 还只是一个半成品的bean 存入singletonFactories中

                执行属性注入时需要一个mapper 这时的容器中还没有mapper 

                mapper实例化对象 加入singletonFactories中

                singletonFactories中此时存储了 mapper 与 service

                mapper属性注入 在三级缓存中获取到service, service从三级缓存移到二级缓存

                mapper执行完bean的生命周期成为一个完整的bean存储到单例池中,删除二三级缓存

                回溯到service的属性注入 此时容器中已经有了mapper,直接注入 , 然后执行完生命周期成为完整bean存入单例池,删除二三级缓存。

由于源码的翻阅过程特别繁琐 需要特别长的时间 这里使用文字简洁描述一下如果工作的

写一段测试代码试试把...

 public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("Bean的生命周期/Beanfactory.xml");
        Object bean1 = applicationContext.getBean("service");
        Object bean2 = applicationContext.getBean("mapper");
        System.out.println(bean1);
        System.out.println(bean2);
    }

控制台输出结果:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值