spring三级缓存总结

前言

其实说到spring的三级缓存,也是经常被提到,自己也看过对应的源码,但是,总觉得自己还是没有真正的理解,为什么这样说呢,因为每次看到三级缓存相关的技术问题,自己心里感觉还是迷糊的,不知道为什么要有三级缓存,一级缓存不行吗,二级缓存是干啥的,以及和三级缓存的区别等,这些问题自己还是回答不出来,这样的情况其实还是对于知识的一知半解,并且缺乏总结

过程

其实自己在看spring的源码,通过几个功能原理的阅读,自己也有了一定的积累,所以对于三级缓存相关的代码,自己还是知道的,但是对于设计者的思路,自己还是不太清晰,这就需要借助一些相关的文章,看看大佬级别的解读,自己可以从中吸收一些营养。主要有以下两篇文章,写的很好,自己对照着理解以及代码的查阅,确实有了自己的思考和见解,文章链接如下:
https://blog.csdn.net/qq_40277163/article/details/124399551
https://zhuanlan.zhihu.com/p/496273636

整理总结

如果想理解设计的原理,你可以把自己当作spring的设计者,遇到循环依赖的时候,应该怎么解决。

  • 首先,我会这样想,只设计一个缓存是否能解决问题,似乎是可以的,只要一个三级缓存其实就可以,因为三级缓存现状是bean实例化后初始化前的状态,对于一个对象,实例化这个步骤不能少,不然就可能出现空指针的情况,所以三级缓存是必要的。因为这个bean的引用是同一个,所以当出现循环依赖的时候,直接从三级缓存中获取然后就可以继续往下执行了。这样的话,其实就是把一级缓存省略了,因为一级缓存是最终态,相当于三级缓存中的bean在spring容器启动的过程中,一直是个中间态,功能实现其实也能说通。
  • 是不是只要一个三级缓存,就能解决循环依赖问题了?答案是不能,上述我们描述的情况,其实只是spring容器启动的一个场景,就是这个bean不需要被创建代理,没有任何aop的逻辑,一旦这个bean加上了@Cacheable这样的注解,这个bean在spring启动过程中就会被创建代理类来代理接口的实现,在这样的情况下,只要一个三级缓存就解决不了循环依赖的问题。
  • 因为此时这个bean和创建的代理类根本就是两个不一样的对象,比如A依赖B,B依赖C和D,C和D又都依赖A,如果只要一个三级缓存,那么C和D依赖的A最终就不是一个代理类,不符合业务功能,所以就需要一个二级缓存来处理需要创建代理这样的情况。提前走代理类的处理流程,满足代理条件的话,就用代理类来包装bean,让C和D中的依赖是这个bean的代理,然后这个bean可以继续后续的初始化流程,保证其他依赖该bean的注入都是同一个代理类,这个就是二级缓存存在的意义
  • 最后,因为spring的设计者也不确定在bean的创建过程中,需不需要创建代理类,所以他使用三级缓存的设计,实例化之后放入三级缓存,如果在存在循环依赖的时候,提前走创建代理类的逻辑,保证代理类的唯一性,然后存入二级缓存(其实算是懒加载处理),最后初始化完成,放入一级缓存,删除二级和三级缓存。

你可能感兴趣的:(Spring系列文章,spring,三级缓存)