三级缓存结构:

  • 代码清单2-17 DefaultSingletonBeanRegistry中的三级缓存Map定义代码
/** 单例对象的缓存: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** 提前暴露的单例对象的缓存: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** 单例对象工厂的缓存: bean name --> ObjectFactory*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

getSingleton()方法分析:

在bean的加载过程中,单例在Spring的同一容器内只会被创建一次,后续再获取bean直接从单例缓存中获取。

尝试加载实例的顺序:

singletonObjects -> earlySingletonObjects -> singletonFactories

尝试加载实例的原则:将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时需要依赖上个bean,则直接使用ObjectFactory

首先尝试从singletonObjects里面获取实例,如果获取不到再从earlySingleton- Objects里面获取,如果还获取不到,再尝试从singletonFactories里面获取beanName对应的ObjectFactory,然后调用这个ObjectFactory的getObject来创建bean,并放到earlySingleton-Objects里面去,并且从singletonFacotories里面remove掉这个ObjectFactory,而对于后续的所有内存操作都只为了循环依赖检测时候使用,也就是在allowEarlyReference为true的情况下才会使用。

《Spring源码深度解析(第2版)》
singletonObjects:用于保存BeanName和创建bean实例之间的关系,bean name --> bean instance。singletonFactories:用于保存BeanName和创建bean的工厂之间的关系,bean name --> ObjectFactory。earlySingletonObjects:保存BeanName和创建bean实例之间的关系,当一个单例bean被放到这里面后,那么当bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环引用。registeredSingletons:用来保存当前所有已注册的bean。

《Spring源码深度解析(第2版)》

本篇文章来源于微信公众号: 海盐架构笔记



微信扫描下方的二维码阅读本文

此作者没有提供个人介绍
最后更新于 2023-06-20