Spring三级缓存是如何作用的

什么是三级缓存

  • singletonObjects: 一级缓存,用于保存实例化、注入、初始化完成的bean实例【完全体】
  • earlySingletonObjects: 二级缓存,用于保存实例化完成的bean实例
  • singletonFactories: 三级缓存,用于保存bean创建工厂,以便于后面扩展有机会创建代理对象。

什么是循环依赖

一个或者多个对象之间存在直接或者间接的依赖关系,形成一个环状依赖。
存在:自己依赖自己;两者互相依赖(如下图);多个对象间接依赖。
在这里插入图片描述
代码示例,以下会以此代码示例讲解:

@Service
public class DemoServiceImpl_01 {

    @Autowired
    private DemoServiceImpl_02 demoServiceImpl_02;
}

@Service
public class DemoServiceImpl_02 {
    @Autowired
    private DemoServiceImpl_01 demoServiceImpl_01;
}

bean加载流程

在这里插入图片描述

spring能解决循环依赖的本质

spring能解决循环依赖的本质是:bean的实例化和初始化是分开执行的,利用三级缓存的设置可以将实例化后的对象缓存到二级缓存,在依赖注入的时候会先尝试从一级缓存获取对象,如果没有再尝试从二级缓存,三级缓存中去获取。
以下我们先举个循环依赖的例子:

// TestService1,TestService2都只有唯一一个构造器,实例化的时候就必须处理依赖注入的对象TestService2
// 但是依赖注入的对象TestService2的实例化也依赖TestService1的实例化,因此造成循环依赖

@Service
public class TestService1 {

    public TestService1(TestService2 testService2) {
    }
}

@Service
public class TestService2 {

    public TestService2(TestService1 testService1) {
    }
}

运行结果:
Requested bean is currently in creation: Is there an unresolvable circular reference?

探究三级缓存的必要性

一级缓存是否必须存在

一级缓存,用于保存实例化、注入、初始化完成的bean实例【完全体】,毋庸置疑,一级缓存必须存在。

二级缓存是否必须存在

讨论这个问题,我们得知道三级缓存中的ObjectFactory具体是干什么的?
在这里插入图片描述

从源码可以看出,在bean实例化之后,初始化之前,spring会将实例化好的bean封装成一个ObjectFactory对象放入三级缓存,那么这么做是为什么呢?其实是为了做AOP增强。
在这里插入图片描述
AbstractAutoProxyCreator 继承 SmartInstantiationAwareBeanPostProcessor,SmartInstantiationAwareBeanPostProcessor正是ObjectFactory#getEarlyBeanReference里面要处理的后置处理器。

在这里插入图片描述
那么回到正题,知道了三级缓存的作用,为什么二级缓存必须得有呢?
在这里插入图片描述
当调用getBean()时,会先尝试从缓存中获取(如上图代码),这时候是一级缓存->二级缓存->三级缓存,这里面会有一个细节:从三级缓存中取完后会将对应ObjectFactory删掉,然后将获取的对象放入二级缓存;这时候如果没有二级缓存的话,每次走到此处都要从三级缓存中获取对象,如果对象需要代理,那么每次获取到的代理对象将会不是同一个对象,故二级缓存必须有。

三级缓存是否必须存在

其实我一直有一个疑问,我是否可以不要三级缓存,在添加三级缓存时,我立马处理bean的增强逻辑,并将增强后的bean存入二级缓存?

其实从bean生命周期设计的角度来看,最好是当我实例化,初始化完成后再去考虑增强的事,从源码设计来看,利用三级缓存存储ObjectFactory来实现AOP增强的滞后处理。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值