spring 循环依赖

举报
周杰伦本人 发表于 2022/05/10 20:44:46 2022/05/10
【摘要】 spring 循环依赖AService出现了循环依赖的情况下---->对AService提前进行AOPaService Bean的生命周期creatingSet<aService>实例化-- -AService不完整对象 (new AService()) 原始对象— >第三级缓存<' aService',lambda(AService原始对 象, beanName, BeanDefinit...

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代理对象

  6. 放入单例池

  7. 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;
	}

总结

这篇文章从Spring一个实例的生命周期说起,包括如何进行实例化,在实例化过程中涉及到循环依赖的问题,了解到Spring是如何使用三级缓存来解决循环依赖问题的,并从源码角度看了一下三级缓存的实现过程,一级缓存存的是完整的对象,使用ConcurrentHashMap保证原子性二级缓存和三级缓存存的是不完整的对象,使用synchronized来保证原子性,希望这篇文章对你有所帮助,喜欢这篇文章的话就给我点个赞吧!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。