spring循环依赖 (1-6)

spring循环依赖

如何底层解决循环依赖原理

Map<String, Object> singletonObjects 一级缓存完成对象(对象和属性都已经赋值)
Map<String, Object> earlySingletonObjects 二级缓存 不完整对象 对象已经创建但是属性缺没有赋值 早期对象
Map<String, ObjectFactory<?>> singletonFactories 三级缓存(只初始化,没有给属性赋值对象) 存放提前曝光对象

对象循环引用 (java的引用传递)

HashMap<Object, Object> objectHashMap = new HashMap<Object, Object>();
// 1.添加A对象
objectHashMap.put("aService", new AService());
// 2.B对象从三级缓存中查找到B
objectHashMap.put("bService", new BService());
AService aService = (AService) objectHashMap.get("aService");
BService bService = (BService) objectHashMap.get("bService");
bService.aService = aService;
//3.A对象需要设置
aService.bService = bService;

spring 对象初始化过程

  1. doGetBean 创建对象
  2. getSingleton
    String beanName 是否有缓存对象,如果有直接返回。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1.从一级缓存中查询是否存在该对象 查询完整的对象
   Object singletonObject = this.singletonObjects.get(beanName);
//2.没有创建对象,并且该对象正在创建(标记为循环依赖的查询)
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      synchronized (this.singletonObjects) {
// 3.查询二级缓存中是否存在对象
         singletonObject = this.earlySingletonObjects.get(beanName);
         if (singletonObject == null && allowEarlyReference) {
// 4.查询三级缓存是否存在对象,如果存在放入到二级缓存中。
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
               singletonObject = singletonFactory.getObject();
               this.earlySingletonObjects.put(beanName, singletonObject);
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return singletonObject;
}
  1. getSingleton --> beforeSingletonCreation(beanName);
// 标记对象是否开始创建
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
  1. createBean→doCreateBean创建对象
  2. createBeanInstance 基于反射或者cglib创建对象(注意对象不完整,因为属性没有设置的)
  3. A将不完整对象(婴儿对象)设置到我们的三级缓存中。
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		synchronized (this.singletonObjects) {
			if (!this.singletonObjects.containsKey(beanName)) {
				this.singletonFactories.put(beanName, singletonFactory);
				this.earlySingletonObjects.remove(beanName);
				this.registeredSingletons.add(beanName);
			}
		}
	}
  1. populateBean给对象属性赋值(检查到现在依赖B对象,这时候肯定需要创建B对象)
  2. 继续走duGetBean 1-6流程 发现B对象中依赖与A对象
  3. 继续调用getSingleton方法 A对象已经在三级缓存中存在数据,直接获取三级缓存中。
    applyPropertyValues →valueResolver.resolveValueIfNecessary →
    resolveReference(argName, ref)
  4. 调用自定义init方法 (初始化)

在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值