spring如何使用三级缓存解决循环依赖

本文详细介绍了在SpringBoot中如何通过自定义BeanPostProcessor实现三级缓存机制,避免循环依赖,并展示了如何在代码中使用这个机制获取bean。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

三级缓存的实现原理是:

1.在创建 bean 实例时,将正在创建的 bean 放入一个“当前正在创建的 bean”集合中。

2.当 bean 实例化完成后,将其放入一个“已经创建好的 bean”集合中。

3.当需要使用到该 bean 时,先从“当前正在创建的 bean”集合中查找是否存在该 bean,如果存在则说明出现了循环依赖,抛出异常;否则从“已经创建好的 bean”集合中查找是否存在该 bean,如果存在则返回该 bean,否则创建 bean 并放入“已经创建好的 bean”集合中。

在 Spring Boot 中,可以通过自定义 BeanPostProcessor 来实现三级缓存。具体步骤如下:

1.创建一个类,实现 BeanPostProcessor 接口,并重写 postProcessBeforeInitialization 和 postProcessAfterInitialization 方法。

2.在 postProcessBeforeInitialization 方法中,将正在创建的 bean 放入“当前正在创建的 bean”集合中。

3.在 postProcessAfterInitialization 方法中,将已经创建好的 bean 放入“已经创建好的 bean”集合中。

4.在需要使用到该 bean 的地方,通过 ApplicationContext.getBean() 方法获取该 bean,自动触发 BeanPostProcessor 的 postProcessBeforeInitialization 和 postProcessAfterInitialization 方法,从而实现三级缓存。

@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {

    private Map<String, Object> singletonObjects = new ConcurrentHashMap<>(); // 已经创建好的 bean 集合
    private Set<String> singletonCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>()); // 当前正在创建的 bean 集合

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (singletonCurrentlyInCreation.contains(beanName)) { // 如果当前正在创建的 bean 集合中包含该 bean,则说明出现了循环依赖,抛出异常
            throw new BeanCurrentlyInCreationException(beanName);
        }
        singletonCurrentlyInCreation.add(beanName); // 将该 bean 放入“当前正在创建的 bean”集合中
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        singletonCurrentlyInCreation.remove(beanName); // 将该 bean 从“当前正在创建的 bean”集合中移除
        singletonObjects.put(beanName, bean); // 将该 bean 放入“已经创建好的 bean”集合中
        return bean;
    }

    public Object getSingleton(String beanName) {
        return singletonObjects.get(beanName);
    }
}

在需要使用到该 bean 的地方,可以通过以下方式获取:

CustomBeanPostProcessor customBeanPostProcessor = applicationContext.getBean(CustomBeanPostProcessor.class);
Object bean = customBeanPostProcessor.getSingleton(beanName);
if (bean == null) {
    bean = applicationContext.getBean(beanName);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值