首页 > 其他分享 >【白话Spring】三级缓存

【白话Spring】三级缓存

时间:2024-09-11 22:24:25浏览次数:3  
标签:缓存 白话 Spring ServiceA Bean 实例 三级

快速导航

一、Spring的三级缓存是什么?

三级缓存

简单来说,就是map,和我们在开发中new的map没有任何区别。

/** Cache of singleton objects: bean name to bean instance. */
// 一级缓存:存储完整的单例对象。key是对象名称,value是对象实例。
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** Cache of singleton factories: bean name to ObjectFactory. */
// 三级缓存:存储生成单例对象的工厂对象。key是对象名称,value是工厂实例。
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

/** Cache of early singleton objects: bean name to bean instance. */
// 二级缓存:存储实例化后的对象(对象未注入属性和初始化)。key是对象名称,value是对象实例。
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

从上面的代码中可以看出,三级缓存就是3个全局的Map。

只是一级缓存和二级缓存使用的是线程安全的容器 ConcurrentHashMap 保存。

这里提两个问题,大家可以思考一下:
1.这里的三个容器变量名为什么都带着singleton?
2.为什么一级缓存和二级缓存使用的ConcurrentHashMap,而三级缓存使用HashMap?

容器只是个工具,怎么用才是我们需要了解的关键,什么时候给容器里存入Bean,把Bean存入哪个容器,什么时候清空容器,这就不得不了解一下Spring中Bean的生命周期了。

SpringBean 的生命周期:

BeanFactory关于Bean初始化注释:

  1. BeanNameAware’s setBeanName 设置实例名称
  2. BeanClassLoaderAware’s setBeanClassLoader 设置实例类加载器
  3. BeanFactoryAware’s setBeanFactory 设置Bean工厂
  4. EnvironmentAware’s setEnvironment 设置环境
  5. EmbeddedValueResolverAware’s setEmbeddedValueResolver 设置内嵌的值解析器
  6. ResourceLoaderAware’s setResourceLoader (only applicable when running in an application context)
  7. ApplicationEventPublisherAware’s setApplicationEventPublisher (only applicable when running in an application context)
  8. MessageSourceAware’s setMessageSource (only applicable when running in an application context)
  9. ApplicationContextAware’s setApplicationContext (only applicable when running in an application context)
  10. ServletContextAware’s setServletContext (only applicable when running in a web application context)
  11. postProcessBeforeInitialization methods of BeanPostProcessors
  12. InitializingBean’s afterPropertiesSet
  13. a custom init-method definition
  14. postProcessAfterInitialization methods of BeanPostProcessors

On shutdown of a bean factory, the following lifecycle methods apply:

  1. postProcessBeforeDestruction methods of DestructionAwareBeanPostProcessors
  2. DisposableBean’s destroy
  3. a custom destroy-method definition

分析:

Bean的创建过程:
  1. 前面10个都是 xxxAware.setXXX()方法
  2. 然后就是 BeanPostProcessors.postProcessBeforeInitialization()
  3. InitializingBean.afterPropertiesSet()
  4. 自定义的init()方法
  5. BeanPostProcessors.postProcessAfterInitialization()
Bean的销毁过程:
  1. DestructionAwareBeanPostProcessors.postProcessBeforeDestruction()
  2. DisposableBean.destroy()
  3. 自定义的destroy()方法

Spring Bean创建的核心逻辑:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

  1. createBeanInstance()实例化Bean
    Bean实例化
  2. populateBean() 填充属性和 initializeBean() 初始化
    Bean属性填充和初始化
  3. 进入initializeBean()
    初始化过程
  4. invokeAwareMethods()源码
    在这里插入图片描述
  5. applyBeanPostProcessorsBeforeInitialization()
    在这里插入图片描述
  6. invokeInitMethods()
    在这里插入图片描述7. applyBeanPostProcessorsAfterInitialization()在这里插入图片描述

二、Spring的三级缓存解决了什么问题?

1.循环依赖问题

设想一下没有三级缓存的循环依赖问题:ServiceA依赖ServiceB,ServiceB依赖ServiceA

  1. ServiceA实例化,然后在属性填充的时候,发现依赖ServiceB。在Spring容器中找ServiceB,没有找到。
  2. ServiceA暂停属性注入,开始实例化ServiceB,然后在属性填充的时候,发现依赖ServiceA,于是又在Spring容器中找ServiceA,同样没有找到。
  3. GG了。

加入了三级缓存:

  1. ServiceA实例化,之后将实例化的不完整的实例ServiceA放入三级缓存。然后在属性填充的时候,发现ServiceA依赖ServiceB。在Spring容器中的一级缓存、二级缓存和三级缓存中找ServiceB,没有找到。
  2. ServiceA暂停属性注入,开始实例化ServiceB,同样将不完整的ServixcB实例放入三级缓存。然后在属性填充的时候,发现依赖ServiceA,于是又在Spring容器中找ServiceA,先找了一级缓存和二级缓存,没找到。在三级缓存中找到了不完整的实例ServiceA,然后将ServiceB从三级缓冲中移除,放入二级缓存,然后成功的对ServiceB进行了属性填充和初始化操作,然后从二级缓存移除,放入一级缓存。
  3. ServiceA继续属性注入,依次放入二级缓存和一级缓存。

问题:
解决循环依赖的问题有两级缓存就够了,为什么要用三级缓存呢?
答:因为Spring需要支持AOP

2.支持Spring的AOP

在Bean被AOP进行了切面代理之后,三级缓存中的singletonFactory获取到的对象实例是目标Bean的一个代理对象。
每次获取到的都是新的代理对象,就破坏了Spring解决循环依赖问题的基础,即所有的对象都是单例的。
而加入了二级缓存以后,代理对象也是只获取一次,然后放入二级缓存备用。

参考资料:

https://topjavaer.cn/advance/excellent-article/6-spring-three-cache.html#%E4%B8%89%E7%BA%A7%E7%BC%93%E5%AD%98%E8%A7%A3%E5%86%B3%E5%BE%AA%E7%8E%AF%E4%BE%9D%E8%B5%96

https://www.mianshiya.com/bank/1790683494127804418/question/1780933295387734017

标签:缓存,白话,Spring,ServiceA,Bean,实例,三级
From: https://blog.csdn.net/qq_22129643/article/details/142137210

相关文章