您现在的位置是:主页 > news > 阿里云 b2c网站建设/网站制作400哪家好
阿里云 b2c网站建设/网站制作400哪家好
admin2025/5/13 5:04:49【news】
简介阿里云 b2c网站建设,网站制作400哪家好,运城建设局网站,java做网站需要数据库吗spring中的循环依赖 循环依赖的场景 1.构造器的循环依赖 2.field属性的循环依赖 如果两个对象是构造器的循环依赖,这中是没有什么办法解决,当A构造器依赖B,B构造器依赖A,无法提前实例化,以及缓存,因此无…
spring中的循环依赖
循环依赖的场景
1.构造器的循环依赖
2.field属性的循环依赖
如果两个对象是构造器的循环依赖,这中是没有什么办法解决,当A构造器依赖B,B构造器依赖A,无法提前实例化,以及缓存,因此无法处理。
spring对bean的创建是分三个步骤:1.通过构造器new出对象;2.设置属性;3.执行设置的初始化函数。field属性的循环依赖时,我们可以完成
构造器的执行,得到对象的引用地址,传给依赖的属性,后面再对这个对象设置相关的属性。就处理了field属性的循环依赖。
filed循环依赖示例
@service
public class ServiceA {@autowiredprivate ServiceB serviceb;}@service
public class ServiceB{@autowiredprivate ServiceA servicea;}@service
public class Demo {@Autowiredprivate ServiceA servicea;@autowiredprivate ServiceB serviceb;
}
当spring创建Demo时,先执行默认无参构造器,创建对象Demo,然后设置属性servicea,serviceb,当创建serviceA时,先执行构造器,获得引用地址,加入缓存,填充A的属性再创建serviceB,
执行B的构造器,填充属性,从缓存中查到A的引用地址,填充,返回B的引用,给A; A,B完成创建。
spring在处理field的循环依赖使用了三级缓存方案。
源码分析
protected <T> T doGetBean(){// Eagerly check singleton cache for manually registered singletons.// 从缓存中查询beanObject sharedInstance = getSingleton(beanName);
}
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {/** Cache of singleton objects: bean name --> bean instance */// 一级缓存: 完整的beanprivate final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);/** Cache of early singleton objects: bean name --> bean instance */// 二级缓存: 只执行了构造器的beanprivate final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);/** Cache of singleton factories: bean name --> ObjectFactory */// 三级缓存:只执行了构造器的ObjectFactoryprivate final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);protected Object getSingleton(String beanName, boolean allowEarlyReference) {// 一级缓存查询,是否存在Object singletonObject = this.singletonObjects.get(beanName);//如果不存在,并且bean正在创建中if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {// 从二级缓存查询singletonObject = this.earlySingletonObjects.get(beanName);//二级缓存不存在以及允许从三级缓存中查询ObjectFactoryif (singletonObject == null && allowEarlyReference) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {//三级缓存查询到了ObjectFactory,通过ObjectFactory获取到引用地址singletonObject = singletonFactory.getObject();//从三级缓存获取到了,加入到二级缓存this.earlySingletonObjects.put(beanName, singletonObject);//在从三级缓存中移除this.singletonFactories.remove(beanName);}}}}return (singletonObject != NULL_OBJECT ? singletonObject : null);}//加入一级缓存存储ObjectFactory,此时只是执行了构造器,还未填充属性,获得了引用地址,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);}}}//一级缓存,完成bean的创建,加入到一级缓存protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {// 加入一级缓存,并且从二,三级缓存移除this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));this.singletonFactories.remove(beanName);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}}
总结
1.spring可以处理field属性的循环依赖,不能处理构造器的循环依赖
2.spring通过三级缓存解决了循环依赖问题
3.使用三级缓存解决循环依赖的基础是:spring对bean的创建分为三个步骤: 执行构造器、填充属性、执行初始化方法
参考
Spring中的循环依赖解决详解
Spring-bean的循环依赖以及解决方式
spring中bean创建过程中的扩展点