栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring容器 之 循环依赖终极讲解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring容器 之 循环依赖终极讲解

一、问题重现 情况一

SelfDependencyBean 中含有 SelfDependencyBean 属性并且需要依赖注入。

情况二

OrderServiceImpl 中含有 UserServiceImpl 属性并且需要依赖注入;
UserServiceImpl 中含有 OrderServiceImpl 属性并且需要依赖注入。

反正嘛,就是形成了循环的依赖关系就是这个意思。

如果单例的情况,Spring会自动帮你解决;而多例的情况,从逻辑上是会造成无限递归导致内存溢出,所以spring并不会帮你擦屁股哦。

二、知识预热 1. Spring容器中使用到的集合
  • singletonsCurrentlyInCreation:准备初始化的对象
  • singletonObjects:已实例化+赋值完成对象
  • earlySingletonObjects:早期对象(仅完成了实例化的对象)
  • singletonFactories:准备实例化的objectFactory
2. 重要代码(节选+伪代码)

备注

  1. >>> 是调用的意思
  2. -> 是lambda表达式

DefaultListableBeanFactory

	// 对象注册bean入口
	getBean(beanName) >>> doGetBean(name, null, null, false) {
		getSingleton(beanName)
		getSingleton(beanName, () -> createBean(beanName, mbd, args))
	}

AbstractBeanFactory

	// 从缓存、早期对象、objectFactory集合中获取Bean对象
	getSingleton(beanName, true)
	
	// 标记当前bean对象的状态存入到集合中,并完成创建赋值
	getSingleton(beanName, () -> createBean(beanName, mbd, args)) {
		// 标记当前bean为初始化状态
		beforeSingletonCreation(beanName)
		// 创建对象,并且完成属性赋值
		singletonObject = singletonFactory.getObject() -> createBean(beanName, mbd, args)
		// 移除当前bean的初始化状态
		afterSingletonCreation(beanName)
		// 加入缓存
		addSingleton(beanName, singletonObject)
	}

AbstractAutowireCapableBeanFactory

	// 创建对象,并且完成属性赋值
	createBean(beanName, mbd, args) >>> doCreateBean(beanName, mbdToUse, args) {
		// 使用反射技术,实例化对象
		instanceWrapper = createBeanInstance(beanName, mbd, args);
		// 当前类是单例 && 允许循环依赖 && 当前bean为初始化状态
		if (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)){
			// 当前bean的工厂类加到准备实例化的objectFactory集合中
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))
		}
		// 属性赋值
		populateBean(beanName, mbd, instanceWrapper);
		// 执行bean的各种init方法+执行前后置处理器
		exposedObject = initializeBean(beanName, exposedObject, mbd);
		return instanceWrapper;
	}

	// 当前bean的工厂类加到准备实例化的objectFactory集合中
	addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))

	// 属性赋值
	populateBean(beanName, mbd, instanceWrapper) {
		...
		getBean(beanName)
		...
	}
简单粗暴 —— Spring执行过程
getBean(OrderServiceImpl) >>> doGetBean(OrderServiceImpl, null, null, false) {
	getSingleton(OrderServiceImpl) == null
	getSingleton(OrderServiceImpl, () -> createBean(OrderServiceImpl, mbd, args)) {
		// 标记 OrderServiceImpl 为初始化状态
		beforeSingletonCreation(OrderServiceImpl)
		// 创建对象,并且完成属性赋值
		singletonObject = singletonFactory.getObject() -> createBean(OrderServiceImpl, mbd, args) >>> doCreateBean(OrderServiceImpl, mbdToUse, args) {
			// 使用反射技术,实例化对象
			instanceWrapper = createBeanInstance(OrderServiceImpl, mbd, args);
			// OrderServiceImpl 是单例 && 允许循环依赖 && 当前bean为初始化状态
			if (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(OrderServiceImpl)){
				// OrderServiceImpl 工厂类加到准备实例化的objectFactory集合中
				addSingletonFactory(OrderServiceImpl, () -> getEarlyBeanReference(OrderServiceImpl, mbd, bean))
			}
			// 属性赋值
			populateBean(OrderServiceImpl, mbd, instanceWrapper) >>> ... >>> getBean(UserServiceImpl)  >>> doGetBean(UserServiceImpl, null, null, false) {
				getSingleton(UserServiceImpl) == null
				getSingleton(UserServiceImpl, () -> createBean(UserServiceImpl, mbd, args)) {
					// 标记 UserServiceImpl 为初始化状态
					beforeSingletonCreation(UserServiceImpl)
					// 创建对象,并且完成属性赋值
					singletonObject = singletonFactory.getObject() -> createBean(UserServiceImpl, mbd, args) >>> doCreateBean(UserServiceImpl, mbdToUse, args) {
						// 使用反射技术,实例化 UserServiceImpl
						instanceWrapper2 = createBeanInstance(UserServiceImpl, mbd, args);
						// UserServiceImpl 是单例 && 允许循环依赖 && 当前bean为初始化状态
						if (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(UserServiceImpl)){
							// UserServiceImpl 工厂类加到准备实例化的objectFactory集合中
							addSingletonFactory(UserServiceImpl, () -> getEarlyBeanReference(UserServiceImpl, mbd, bean))
						}
						// 属性赋值
						populateBean(UserServiceImpl, mbd, instanceWrapper2) >>> ... >>> getBean(OrderServiceImpl) >>> doGetBean(OrderServiceImpl, null, null, false) {
							getSingleton(OrderServiceImpl) == OrderServiceImpl
						}
						// 执行bean的各种init方法+执行前后置处理器
						exposedObject = initializeBean(UserServiceImpl, exposedObject, mbd);
						return instanceWrapper2;
					}
					// 移除当前bean的初始化状态
					afterSingletonCreation(beanName)
					// 加入缓存
					addSingleton(beanName, singletonObject)
				}
			}
			// 执行bean的各种init方法+执行前后置处理器
			exposedObject = initializeBean(OrderServiceImpl, exposedObject, mbd);
			return instanceWrapper;
		}
		// 移除当前bean的初始化状态
		afterSingletonCreation(beanName)
		// 加入缓存
		addSingleton(beanName, singletonObject)
	}
}

其实Spring的内部是形成了递归调用的循环算法。就是getBean()方法中,执行各种操作之后,又走回getBean() 方法。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/489009.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号