spring三级缓存解决aop代理循环依赖图示

spring三级缓存解决aop代理循环依赖图示

三级缓存

  • 每一级缓存就是一个Map,就是存放的<beanName,对象>。spring容器的完整getBean流程是一级缓存----->二级缓存----->三级缓存----->都没有就创建----->doCreateBean
  • 一级缓存singletonObjects: 已经创建完成可以直接使用的单例对象。通常说的spring容器,就是说的这个,创建完成的对象需要一个map存储。
  • 二级缓存earlySingletonObjects: 早期对象,还在创建过程中的对象,可能是代理对象,也可能就是普通对象。
  • 三级缓存singletonFactories: 用于生成代理对象获取返回自身的对象工厂。

正常生命周期

  • 两个Bean相互依赖,并且不需要Aop代理。这种正常的生命周期,是可以通过二级缓存来解决循环依赖的。核心思想是: 通过二级缓存提前曝光未创建完成的Bean
  • 然后属性填充时从二级缓存earlySingletonObjects中获取,然后赋值,是可以解决普通循环依赖的。
  • 但是如果是需要产生代理对象的循环依赖是解决不了的。

首先来看普通循环依赖的结构:a和b相互依赖。
在这里插入图片描述

使用二级缓存【singletonObjects , earlySingletonObjects】来解决的流程是这样的:
在这里插入图片描述

Aop代理循环依赖问题

  • 先看一下aop循环依赖最终的结构应该是怎么样的。
    在这里插入图片描述
  • 如果是还是用刚刚的二级缓存来解决代理循环依赖问题,是有问题的,看图:
    在这里插入图片描述

三级缓存解决Aop循环依赖

  • 可以看出代理对象的循环依赖核心是需要填充属性时,应该填充的是代理对象,而不是之前的源对象。也就是说:填充属性时,如果是需要代理,应该aop提前创建代理

  • 流程如下图:
    在这里插入图片描述

  • 刚刚已经说了如果用一级缓存和二级缓存组合是不能解决有aop的循环依赖的,那如果是使用一级缓存 singletonObjects + 三级缓存 singletonFactories可以解决循环依赖吗?

  • 我觉得是不可以的。从上面的流程可以看到,最终是需要将源A对象替换为代理A对象的,而这是从二级缓存中获取的。也就是提前创建的代理对象A需要有存储中间的容器,二级缓存就是这个中间容器。

  • 当然也可以直接把代理对象A存放到一级缓存singletonObjects 中,但是此时对象A还在创建过程中,还没有填充属性,然后又另外的线程从容器中获取对象A,就会拿到这个还未创建完成的代理A对象。

  • 而且直接将创建过程中的代理A对象存放入一级缓存singletonObjects ,我觉得是不符合spring的设计理念的,一级缓存singletonObjects 的定义就是存放已经创建完成可以直接使用的单例对象。

总结

  • 二级缓存可以解决没有aop的循环依赖。核心思路是使用二级缓存来提前曝光创建过程中的对象
  • 使用二级缓存来解决aop循环依赖的问题是:bean对象属性填充的应该是代理对象,而不是源对象。
  • 三级缓存解决aop循环依赖核心思路:打破bean的生命周期,属性赋值时aop提前创建代理对象
  • 如果文章对你有帮助,可以点赞+收藏+关注支持一下

流程图地址

二级缓存解决普通循环依赖

二级缓存aop循环依赖问题

三级缓存解决aop循环依赖问题

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值