文章目录

  • Spring三级缓存类源码分析

Spring三级缓存类源码分析

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {// 1级缓存:存放实例化+属性注入+初始化+代理(如果有代理)后的单例beanprivate final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);// 2级缓存:存放实例化+代理(如果有代理)后的单例beanprivate final Map<String, Object> earlySingletonObjects = new HashMap<>(16);// 3级缓存:存放封装了单例bean(实例化的)的对象工厂private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);// 已经完成注册的单例beanNameprivate final Set<String> registeredSingletons = new LinkedHashSet<>(256);// 正在创建中的beanNameprivate final Set<String> singletonsCurrentlyInCreation =  Collections.newSetFromMap(new ConcurrentHashMap<>(16));// 当前不检查的bean的集合private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<>(16));// 存放异常出现的相关的原因的集合private Set<Exception> suppressedExceptions;// 标志,目前是否在销毁单例中private boolean singletonsCurrentlyInDestruction = false;// 存放一次性bean的缓存private final Map<String, Object> disposableBeans = new LinkedHashMap<>();// 外部bean与被包含在外部bean的所有内部bean集合包含关系的缓存private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);// 指定bean与依赖指定bean的所有bean的依赖关系的缓存private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);// 指定bean与创建这个bean所需要依赖的所有bean的依赖关系的缓存private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);/*** 注册单例对象到一级缓存(若一级缓存中已存在则抛出异常)*/@Overridepublic void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {Assert.notNull(beanName, "Bean name must not be null");Assert.notNull(singletonObject, "Singleton object must not be null");synchronized (this.singletonObjects) {Object oldObject = this.singletonObjects.get(beanName);// 如果一级缓存有,说明已经注册过if (oldObject != null) {throw new IllegalStateException("Could not register object [" + singletonObject +"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");}// 一级缓存没有,开始注册addSingleton(beanName, singletonObject);}}/*** 添加到一级缓存(并移除二级、三级缓存)*/protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {// 加入单例对象到一级缓存this.singletonObjects.put(beanName, singletonObject);// 删除三级缓存this.singletonFactories.remove(beanName);// 删除二级缓存this.earlySingletonObjects.remove(beanName);// 加入已注册的beanthis.registeredSingletons.add(beanName);}}/*** 添加到三级级缓存*/protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");synchronized (this.singletonObjects) {// 如果一级缓存没有,添加对象工厂到三级缓存if (!this.singletonObjects.containsKey(beanName)) {this.singletonFactories.put(beanName, singletonFactory);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}}/*** 获取单例*/@Override@Nullablepublic Object getSingleton(String beanName) {// 允许早期依赖return getSingleton(beanName, true);}/*** 获取单例* 2.如果二级缓存有直接返回* 3.如果三级缓存有,通过singletonFactory.getObject()的到未完成的单例对象,并移除三级缓存,返回未完成的单例对象* @param allowEarlyReference  true:允许早期依赖* @return*/@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {// 如果一级缓存有,直接返回Object singletonObject = this.singletonObjects.get(beanName);// 如果一级缓存没有,但正在创建if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {// 如果二级缓存中有,说明正在加载,则直接返回singletonObject = this.earlySingletonObjects.get(beanName);// 二级缓存也没有,且允许早期依赖if (singletonObject == null && allowEarlyReference) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);// 三级缓存有,调用getObject方法创建bean并放入到二级缓存,并删除三级缓存if (singletonFactory != null) {singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return singletonObject;}/*** 获取单例*/public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");synchronized (this.singletonObjects) {// 一级缓存有,直接返回Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {// 当前正在销毁bean,不能创建if (this.singletonsCurrentlyInDestruction) {throw new BeanCreationNotAllowedException(beanName,"Singleton bean creation not allowed while singletons of this factory are in destruction " +"(Do not request a bean from a BeanFactory in a destroy method implementation!)");}if (logger.isDebugEnabled()) {logger.debug("Creating shared instance of singleton bean '" + beanName + "'");}// 创建前检查,记录正在加载状态beforeSingletonCreation(beanName);boolean newSingleton = false;// 如果当前没有异常,初始化异常集合boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();}try {// 调用getObject方法创建beansingletonObject = singletonFactory.getObject();newSingleton = true;}catch (IllegalStateException ex) {// 有可能是其他方式创建的beansingletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {throw ex;}}catch (BeanCreationException ex) {if (recordSuppressedExceptions) {for (Exception suppressedException : this.suppressedExceptions) {ex.addRelatedCause(suppressedException);}}throw ex;}finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}// 创建后检查,移除加载状态afterSingletonCreation(beanName);}// 如果是新创建的bean,添加到一级缓存(并移除二级、三级缓存)if (newSingleton) {addSingleton(beanName, singletonObject);}}return singletonObject;}}/*** 注册过程中发生的异常,加入到异常集合*/protected void onSuppressedException(Exception ex) {synchronized (this.singletonObjects) {if (this.suppressedExceptions != null) {this.suppressedExceptions.add(ex);}}}/*** 移除单例,这四个缓存同时移除*/protected void removeSingleton(String beanName) {synchronized (this.singletonObjects) {this.singletonObjects.remove(beanName);this.singletonFactories.remove(beanName);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.remove(beanName);}}/*** 单例是否一存在*/@Overridepublic boolean containsSingleton(String beanName) {return this.singletonObjects.containsKey(beanName);}/*** 已注册的单例名称集合*/@Overridepublic String[] getSingletonNames() {synchronized (this.singletonObjects) {return StringUtils.toStringArray(this.registeredSingletons);}}/*** 已注册的单例名称数量*/@Overridepublic int getSingletonCount() {synchronized (this.singletonObjects) {return this.registeredSingletons.size();}}/*** 设置不检查的beanName*/public void setCurrentlyInCreation(String beanName, boolean inCreation) {Assert.notNull(beanName, "Bean name must not be null");if (!inCreation) {this.inCreationCheckExclusions.add(beanName);}else {this.inCreationCheckExclusions.remove(beanName);}}public boolean isCurrentlyInCreation(String beanName) {Assert.notNull(beanName, "Bean name must not be null");return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));}protected boolean isActuallyInCreation(String beanName) {return isSingletonCurrentlyInCreation(beanName);}/*** 是否当前创建的bean*/public boolean isSingletonCurrentlyInCreation(String beanName) {return this.singletonsCurrentlyInCreation.contains(beanName);}/*** 创建前检查,记录正在加载状态*/protected void beforeSingletonCreation(String beanName) {// 如果这个beanName要检查,记录创建状态。如果返回false,说明已经正在创建了,抛异常if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}}/*** 创建后检查,移除加载状态*/protected void afterSingletonCreation(String beanName) {// 如果这个beanName要检查,移除创建状态。如果返回false,说明已经创建完了。抛异常if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");}}/*** 注册一次性bean实例*/public void registerDisposableBean(String beanName, DisposableBean bean) {synchronized (this.disposableBeans) {this.disposableBeans.put(beanName, bean);}}/*** 注册包含的bean*/public void registerContainedBean(String containedBeanName, String containingBeanName) {synchronized (this.containedBeanMap) {// 如果没有key为containingBeanName的value,说明内部bean集合为空,则初始化一个Set<String> containedBeans = this.containedBeanMap.computeIfAbsent(containingBeanName, k -> new LinkedHashSet<>(8));// 如果已经存在了对应关系,则直接返回if (!containedBeans.add(containedBeanName)) {return;}}// 不存在了对应关系,添加对应关系registerDependentBean(containedBeanName, containingBeanName);}/*** 注册依赖的bean*/public void registerDependentBean(String beanName, String dependentBeanName) {String canonicalName = canonicalName(beanName);synchronized (this.dependentBeanMap) {Set<String> dependentBeans = this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));// 如果已经存在了对应关系,则直接返回if (!dependentBeans.add(dependentBeanName)) {return;}}// 不经存在了对应关系,添加对应关系synchronized (this.dependenciesForBeanMap) {Set<String> dependenciesForBean = this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));dependenciesForBean.add(canonicalName);}}/*** dependentBeanName是否依赖beanName*/protected boolean isDependent(String beanName, String dependentBeanName) {synchronized (this.dependentBeanMap) {return isDependent(beanName, dependentBeanName, null);}}/*** dependentBeanName是否依赖beanName*/private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {if (alreadySeen != null && alreadySeen.contains(beanName)) {return false;}String canonicalName = canonicalName(beanName);Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);// bean依赖beanName,直接返回falseif (dependentBeans == null) {return false;}// 有其他bean依赖beanName,且包含了dependentBeanName,返回trueif (dependentBeans.contains(dependentBeanName)) {return true;}// 有其他bean依赖beanName,但是不包含dependentBeanNamefor (String transitiveDependency : dependentBeans) {if (alreadySeen == null) {alreadySeen = new HashSet<>();}alreadySeen.add(beanName);// 是否有循环依赖if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {return true;}}return false;}/*** 是否有其他对象依赖指定bean*/protected boolean hasDependentBean(String beanName) {return this.dependentBeanMap.containsKey(beanName);}/*** 返回依赖指定bean的数组*/public String[] getDependentBeans(String beanName) {Set<String> dependentBeans = this.dependentBeanMap.get(beanName);if (dependentBeans == null) {return new String[0];}synchronized (this.dependentBeanMap) {return StringUtils.toStringArray(dependentBeans);}}/*** 返回指定bean,依赖其他bean的数组*/public String[] getDependenciesForBean(String beanName) {Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(beanName);if (dependenciesForBean == null) {return new String[0];}synchronized (this.dependenciesForBeanMap) {return StringUtils.toStringArray(dependenciesForBean);}}/*** 销毁所有单例*/public void destroySingletons() {if (logger.isTraceEnabled()) {logger.trace("Destroying singletons in " + this);}// 设置当前正在销毁synchronized (this.singletonObjects) {this.singletonsCurrentlyInDestruction = true;}String[] disposableBeanNames;synchronized (this.disposableBeans) {disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());}// 销毁disposableBeans中的所有beanfor (int i = disposableBeanNames.length - 1; i >= 0; i--) {destroySingleton(disposableBeanNames[i]);}// 清空containedBeanMap、dependentBeanMap、dependenciesForBeanMapthis.containedBeanMap.clear();this.dependentBeanMap.clear();this.dependenciesForBeanMap.clear();// 清除所有单例缓存clearSingletonCache();}/*** 清除所有单例缓存*/protected void clearSingletonCache() {synchronized (this.singletonObjects) {// 清除所有单例缓存this.singletonObjects.clear();this.singletonFactories.clear();this.earlySingletonObjects.clear();this.registeredSingletons.clear();// 清除完后,标志恢复为falsethis.singletonsCurrentlyInDestruction = false;}}/*** 销毁单例bean*/public void destroySingleton(String beanName) {// 从缓存中移除removeSingleton(beanName);// 从disposableBeans移除,如果有beanName对应的对象,返回这个对象DisposableBean disposableBean;synchronized (this.disposableBeans) {disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);}// 销毁beandestroyBean(beanName, disposableBean);}/*** 销毁bean*/protected void destroyBean(String beanName, @Nullable DisposableBean bean) {// 获取依赖当前beanName的beanSet<String> dependencies;synchronized (this.dependentBeanMap) {dependencies = this.dependentBeanMap.remove(beanName);}// 移除依赖当前beanName的beanif (dependencies != null) {if (logger.isTraceEnabled()) {logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);}for (String dependentBeanName : dependencies) {destroySingleton(dependentBeanName);}}if (bean != null) {try {bean.destroy();}catch (Throwable ex) {if (logger.isWarnEnabled()) {logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);}}}// 移除beanName的对应关系的beanSet<String> containedBeans;synchronized (this.containedBeanMap) {// Within full synchronization in order to guarantee a disconnected SetcontainedBeans = this.containedBeanMap.remove(beanName);}if (containedBeans != null) {for (String containedBeanName : containedBeans) {destroySingleton(containedBeanName);}}// 这个对象被其他bean依赖,也要移除依赖关系synchronized (this.dependentBeanMap) {for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {Map.Entry<String, Set<String>> entry = it.next();Set<String> dependenciesToClean = entry.getValue();dependenciesToClean.remove(beanName);if (dependenciesToClean.isEmpty()) {it.remove();}}}// 移除当前bean与依赖其他bean的关系this.dependenciesForBeanMap.remove(beanName);}/*** 用于加锁操作,返回singletonObjects,通过方法暴露这个对象。*/@Overridepublic final Object getSingletonMutex() {return this.singletonObjects;}
}

Spring三级缓存源码相关推荐

  1. spring 三级缓存源码分析

    spring中对于循环依赖的解决采用了三级缓存机制,即: Map<String, Object> singletonObjects //第一级缓存,存放初始化完成的bean Map< ...

  2. Spring循环依赖源码剖析

    Spring循环依赖源码剖析 一.场景介绍 二.整理执行流程总结 三.源码分析 编写测试类 /*** 测试循环依赖*/@Testpublic void testCyclicDependence(){A ...

  3. Spring三级缓存详解

    Spring三级缓存是为了解决对象间的循环依赖问题. A依赖B,B依赖A,这就是一个简单的循环依赖. 我们来先看看三级缓存的源码. (1)查看"获取Bean"的源码,注意getSi ...

  4. Spring三级缓存解决循环依赖问题详解

    spring三级缓存解决循环依赖问题详解 前言 这段时间阅读了spring IOC部分的源码.在学习过程中,自己有遇到过很多很问题,在上网查阅资料的时候,发现很难找到一份比较全面的解答.现在自己刚学习 ...

  5. spring三级缓存以及@Async产生循环引用

    spring三级缓存以及@Async产生循环引用 spring三级缓存介绍 三级缓存解除循环引用原理 源码对应 1.获取A,从三级缓存中获取,没有获取到 2.构造A,将A置入三级缓存 构造A(创建A实 ...

  6. spring aop 注入源码解析

    spring aop 注入源码解析 aop启动 AbstractApplicationContext.java @Overridepublic void refresh() throws BeansE ...

  7. Spring IOC 容器源码分析 - 循环依赖的解决办法

    1. 简介 本文,我们来看一下 Spring 是如何解决循环依赖问题的.在本篇文章中,我会首先向大家介绍一下什么是循环依赖.然后,进入源码分析阶段.为了更好的说明 Spring 解决循环依赖的办法,我 ...

  8. Spring IOC 容器源码分析 - 创建原始 bean 对象

    1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...

  9. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

最新文章

  1. R语言ggplot2可视化分组散点图、将图例放置在图像内部的指定区域、自定义缩放图例中点形状pch的大小(增大或者缩小)、change size of shape elements
  2. Linux基础命令介绍十:文本流编辑 sed
  3. android AlertDialog.Builder
  4. android+动画+锯齿,Android当中的防锯齿(Bitmap Canvas )
  5. eclipse中如何导入jar包
  6. 解决 Outlook 2007 客户端下载 OAB 时的错误 0x8004010F
  7. Python 只读属性的实现
  8. 压测瓶颈在mysql_MySQL的性能基线收集及压力测试
  9. 人工智能发展及其伦理问题思考
  10. 2、Fiddler工作原理
  11. 明年,移动应用开发将出现这八大趋势
  12. 数据库系统概念中文版pdf
  13. 我的航拍直升机 控制基站软件的编写历程(2.1)
  14. js全屏图片画廊幻灯片插件
  15. 开源BI工具对比(二):宜信 davinci
  16. 动态规划之矩阵连乘问题详细解读(思路解读+填表+代码)
  17. 计算机存储器与寄存器的区别,存储器和寄存器的区别
  18. 算法训练 调和数列问题
  19. graylog+kafka+zookeeper(单机测试及源码),graylog收集kafka(脚本创建发布订阅方式)存储的消息(四)
  20. 如何让电脑连接上手机的无线网

热门文章

  1. window下cmd命令进入和切换目录
  2. 隐藏nginx版本号,隐藏X-Powered-By
  3. 1970-01-01是什么?为什么计算机起始时间是1970年1月1日
  4. matlab butter stop,Matlab butter函数设计滤波器
  5. 为啥需要RPC,而不是简单的HTTP?
  6. 适配器模式-第三方登录与设计模式的七七八八
  7. SpringMvc文件上传和下载
  8. 进制转换(10转8 2)
  9. 一个向上帝买了挂的男人!
  10. 用c++图形库编写的双人打气球