Java 面试题100篇-01

首先,三级缓存是Spring用于处理单例Bean的创建和解决循环依赖问题的机制。在Spring中,单例Bean是指在整个应用程序上下文中只存在一个实例的Bean。

  1. 一级缓存:一级缓存是一个ConcurrentHashMap,用于存储完全初始化的单例Bean实例。当你通过Spring容器获取一个Bean时,首先会查找一级缓存,如果找到了完全初始化的Bean实例,直接返回。

private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

  1. 二级缓存:二级缓存也是一个Map,用于存储早期(不完全初始化)的Bean实例。当Bean正在创建但尚未完全初始化时,它会被放入二级缓存,以便在解决循环依赖问题时能够提供一个引用。同时,二级缓存中的Bean实例通常会是代理对象。

private final Map<String, Object> earlySingletonObjects = new HashMap<>();

  1. 三级缓存:三级缓存是一个Map,用于存储Bean的工厂对象(ObjectFactory)。这些工厂对象负责创建Bean的实例。当解决循环依赖时,如果一个Bean A依赖于另一个Bean B,Bean B的工厂对象会被放入三级缓存中。这是为了确保在创建Bean A时,可以从三级缓存中获取Bean B的工厂对象,以便创建中的Bean A能够引用Bean B。

private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>();

  1. Bean的创建和获取过程:当你通过Spring容器获取一个Bean时,容器会先检查一级缓存,如果找到完全初始化的Bean实例,直接返回。如果一级缓存中没有,容器会继续检查二级缓存,如果找到早期Bean实例,将其返回。同时,如果Bean A依赖于Bean B,Bean B的工厂对象会被放入三级缓存。容器会使用Bean B的工厂对象来创建中的Bean A,并将Bean A的早期实例放入二级缓存中。最后,当Bean A创建完成后,它会被移动到一级缓存中,三级缓存中的Bean B的工厂对象也会被移除。

这个三级缓存机制在Spring容器中非常重要,因为它解决了循环依赖问题,确保Bean的唯一性和正确初始化。

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
// 一级缓存,用于存储完全初始化的Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

// 二级缓存,用于存储早期(不完全初始化)的Bean
private final Map<String, Object> earlySingletonObjects = new HashMap<>();

// 三级缓存,用于存储创建中的Bean工厂对象
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>();

// 通过Bean名称获取Bean的方法
public Object getSingleton(String beanName) {
    // 首先从一级缓存尝试获取完全初始化的Bean
    Object singletonObject = singletonObjects.get(beanName);
    if (singletonObject != null) {
        return singletonObject;
    }

    // 如果一级缓存中没有,尝试从二级缓存获取早期Bean
    singletonObject = earlySingletonObjects.get(beanName);
    if (singletonObject != null) {
        // 如果早期Bean存在,需要处理循环依赖
        // 这时我们可以使用三级缓存的Bean工厂对象
        // 在后续创建过程中,会将创建中的Bean工厂对象放入三级缓存
        ObjectFactory<?> singletonFactory = singletonFactories.get(beanName);
        if (singletonFactory != null) {
            singletonObject = singletonFactory.getObject();
            // 将早期Bean转移到一级缓存中
            singletonObjects.put(beanName, singletonObject);
            // 移除三级缓存中的Bean工厂对象
            singletonFactories.remove(beanName);
        }
    }

    return singletonObject;
}

// 注册Bean工厂到三级缓存的方法
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    synchronized (this.singletonObjects) {
        if (!this.singletonObjects.containsKey(beanName)) {
            this.singletonFactories.put(beanName, singletonFactory);
            this.earlySingletonObjects.remove(beanName);
        }
    }
}

// ...

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值