写点什么

spring 循环依赖

作者:周杰伦本人
  • 2022 年 7 月 10 日
  • 本文字数:1442 字

    阅读完需:约 5 分钟

spring 循环依赖

AService 出现了循环依赖的情况下---->对 AService 提前进行 AOP


aService Bean 的生命周期


  1. creatingSet<aService>

  2. 实例化-- -AService 不完整对象 (new AService()) 原始对象--- >第三级缓存<' aService',lambda(AService原始对 象, beanName, BeanDefinition)>

  3. 填充 bService 属性- --- >从单例池找 bService--->找不到-->创建 bService

  4. bService Bean 的生命周期

  5. 2.1. 实例化--- BService 对象(new BService())

  6. 2.2. 填充 aService 属性-- >从单例池找 aService--->找不到-->aService 正在创建中-- >aService 出现了循环--->第二级缓存--->第三级缓存-->执行 lambda--->--- >提前 AOP--- >AService 代理对象--->第二级缓存<' aService', AService 代理对象>

  7. 2.3. 填充其他属性

  8. 2.4. 做其他事情

  9. 2.5. 放入单例池

  10. 填充 cService 属性

  11. 做其他事情--- -AOP--- >原始对象被代理对象--- -》AService 代理对象 4.5 从第二级缓存取出 AService 代理对象

  12. 放入单例池

  13. creatingSet . remove( ' aservice')

三级缓存

第一级缓存:单例池 singletonObjects ConcurrentHashMap <beanName, bean 对象>


第二级缓存: earlySingletonObjects HashMap <beanName, bean 对象>


第三级缓存:singletonFactories HashMap <beanName, ObjectFactory( lambda 表达式>


一级缓存存的是完整的对象 二级缓存和三级缓存存的是不完整的对象


一级缓存使用 ConcurrentHashMap 保证原子性


二级缓存和三级缓存两个是一个原子操作 使用 synchronized 来保证


protected Object getSingleton(String beanName, boolean allowEarlyReference) {    // 检查一级缓存singletonObject中是否存在实例    Object singletonObject = this.singletonObjects.get(beanName);    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {      // 如果一级缓存中不存在且当前beanName正在被创建,则锁定一级缓存尝试从二三级缓存中获取      synchronized (this.singletonObjects) {        // 从二级缓存中进行查找,二级缓存为普通HashMap,因为在同步代码块中不会发生并发问题        singletonObject = this.earlySingletonObjects.get(beanName);        if (singletonObject == null && allowEarlyReference) {          // 当某些方法需要提前初始化的时候则会调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在三级缓存singletonFactories          ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);          if (singletonFactory != null) {            // 如果singletonFactory中存在,调用预先设定的getObject方法获取bean            singletonObject = singletonFactory.getObject();            // 记录在二级缓存中,三级缓存删除,earlySingletonObjects和singletonFactories互斥            this.earlySingletonObjects.put(beanName, singletonObject);            this.singletonFactories.remove(beanName);          }        }      }    }    return singletonObject;  }
复制代码

总结

这篇文章从 Spring 一个实例的生命周期说起,包括如何进行实例化,在实例化过程中涉及到循环依赖的问题,了解到 Spring 是如何使用三级缓存来解决循环依赖问题的,并从源码角度看了一下三级缓存的实现过程,一级缓存存的是完整的对象,使用 ConcurrentHashMap 保证原子性二级缓存和三级缓存存的是不完整的对象,使用 synchronized 来保证原子性,希望这篇文章对你有所帮助,喜欢这篇文章的话就给我点个赞吧!

发布于: 2 小时前阅读数: 10
用户头像

还未添加个人签名 2020.02.29 加入

公众号《盼盼小课堂》,多平台优质博主

评论

发布
暂无评论
spring 循环依赖_7月月更_周杰伦本人_InfoQ写作社区