spring 循环依赖

简介: spring 循环依赖

spring 循环依赖

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

aService Bean的生命周期

  1. creatingSet<aService>
  2. 实例化-- -AService不完整对象 (new AService()) 原始对象--- >第三级缓存<' aService',lambda(AService原始对 象, beanName, BeanDefinition)>
  3. 填充bService属性- --- >从单例池找bService--->找不到-->创建bService

    bService Bean的生命周期

    2.1. 实例化--- BService对象(new BService())
    2.2. 填充aService属性-- >从单例池找aService--->找不到-->aService正在创建中-- >aService出现了循环--->第二级缓存--->第三级缓存-->执行lambda--->--- >提前AOP--- >AService代理对象--->第二级缓存<' aService', AService代理对象>
    2.3. 填充其他属性
    2.4. 做其他事情
    2.5. 放入单例池

  4. 填充cService属性
  5. 做其他事情--- -AOP--- >原始对象被代理对象--- -》AService代理对象

4.5 从第二级缓存取出AService代理对象

  1. 放入单例池
  2. 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;
    }
相关文章
|
1月前
|
XML 缓存 Java
Spring源码之 Bean 的循环依赖
循环依赖是 Spring 中经典问题之一,那么到底什么是循环依赖?简单说就是对象之间相互引用, 如下图所示: 代码层面上很好理解,在 bean 创建过程中 class A 和 class B 又经历了怎样的过程呢? 可以看出形成了一个闭环,如果想解决这个问题,那么在属性填充时要保证不二次创建 A对象 的步骤,也就是必须保证从容器中能够直接获取到 B。 一、复现循环依赖问题 Spring 中默认允许循环依赖的存在,但在 Spring Boot 2.6.x 版本开始默认禁用了循环依赖 1. 基于xml复现循环依赖 定义实体 Bean java复制代码public class A {
|
2月前
|
存储 缓存 Java
明知面试要问spring循环依赖,很多人还是搞不懂!
Spring中的循环依赖一直是Spring中一个很重要的话题,一方面是因为源码中为了解决循环依赖做了很多处理,另外一方面是因为面试的时候,如果问到Spring中比较高阶的问题,那么循环依赖必定逃不掉。如果你回答得好,那么这就是你的必杀技,反正,那就是面试官的必杀技,这也是取这个标题的原因,当然,本文的目的是为了让你在之后的所有面试中能多一个必杀技,专门用来绝杀面试官!
33 0
|
7天前
|
存储 缓存 Java
Spring解决循环依赖
Spring解决循环依赖
|
24天前
|
缓存 算法 Java
开发必懂的Spring循环依赖图解 Spring 循环依赖
开发必懂的Spring循环依赖图解 Spring 循环依赖
18 1
|
27天前
|
缓存 算法 Java
Spring解决循环依赖
Spring解决循环依赖
19 0
|
1月前
|
Java 开发者 Spring
【Java】Spring循环依赖:原因与解决方法
【Java】Spring循环依赖:原因与解决方法
39 0
|
1月前
|
Java 数据库连接 Spring
Spring Boot 3.2.2整合MyBatis-Plus 3.5.5依赖不兼容问题
Spring Boot 3.2.2整合MyBatis-Plus 3.5.5依赖不兼容问题
47 0
|
1月前
|
消息中间件 运维 监控
|
Java 关系型数据库 MySQL
06_spring_ 依赖注入| 学习笔记
快速学习 06_spring_ 依赖注入
|
28天前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
41 0