前提:
在学习过程中遇到了一二级缓存相关问题,题目中的三个经常记混,特写篇博客记录一下。
一、Spring中的一、二、三级缓存
可用来解决spring中的循环引用相关问题。在讲缓存之前要先熟悉一下spring bean的生命周期。
- 什么是Bean的生命周期
即对象从创建开始到最终销毁的整个过程。 - Bean生命周期:
第一步:实例化Bean-调用构造方法
第二步:Bean属性赋值-调用set方法
第三步:初始化Bean-init方法(初始化前后还可以增加两步,分别为后置处理器的before和after方法)
第四步:使用Bean
第五步:销毁Bean-destroy方法
到此我们了解了bean的生命周期;
接下来可以讲解缓存相关:
-
一级缓存:singletonObjects是用来存放就绪状态的Bean。保存在该缓存中的Bean所实现Aware子接口的方法已经回调完毕,自定义初始化方法已经执行完毕,存在单例池中。
-
二级缓存:半成品,早期bean对象,生命周期还未走完。一般只有处于循环引用状态的Bean才会被保存在该缓存中。
-
三级缓存:singletonFactories是用来存放创建用于获取Bean的工厂类-ObjectFactory实例。在IoC容器中,所有刚被创建出来的Bean,默认都会保存到该缓存中。
-
具体流程:
假设有A、B两个对象,他们循环调用了对方,代码如下:
class A{
B b;
public void a(B b){
}
}
class B{
A a;
public void b(A a){
}
}
流程如下:
1)实例化创建A,同时会创建ObjectFactory对象存入三级缓存中。
2)A在初始化时需要B,接下来走B的创建流程
3)B实例化完成,也会创建ObjectFactory对象存入三级缓存中
4)B需要A,通过三级缓存中获取a的对象存入二级缓存中
5)B通过二级缓存获得A对象,创建成功后存入一级缓存中
6)回到A对象初始化,因为此时B已经走完了全部流程,A可以直接注入B,并存入一级缓存
7)清除二级缓存中的临时对象A
二、Mybatis 一、二级缓存
一级缓存:
也称本地缓存,sqlSession级别的缓存。一级缓存是一直开启的;与数据库同一次回话期间查询到的数据会放在本地缓存中。第二次获取相同的数据,直接从缓存中拿,不会再查数据库。
二级缓存:
全局缓存;基于namespace级别的缓存。一个namespace对应一个二级缓存。
想要开启二级缓存需要在全局配置文件(cacheEnabled)和映射文件()中开启配置