1. Spring中bean的生命周期
构造器创建bean对象
依赖注入
init方法初始化bean对象
使用
销毁
2. Spring循环依赖是怎么回事 循环依赖发生在单例对象A的创建过程中(第一步和第二步)需要其他的单例对象B,而这个单例对象B恰好也需要A。循环依赖主要分两种:构造器循环依赖 和属性循环依赖 。
3. 如和解决循环依赖 Spring通过三级缓存可以解决属性循环依赖,三级缓存主要如下:
1 2 3 4 5 6 7 8 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256 );private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16 );private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16 );
singletonObjects
: 第一级缓存,存放完整可用的单例对象
earlySingletonObjects
: 第二级缓存,存放提前曝光的单例对象
singletonFactories
: 第三级缓存,存放单例对象的工厂
那么三级缓存如何解决属性循环依赖的呢?看一下单例bean的创建过程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 protected Object getSingleton (String beanName, boolean allowEarlyReference) { Object singletonObject = this .singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this .singletonObjects) { singletonObject = this .earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this .singletonFactories.get(beanName); if (singletonFactory != null ) { singletonObject = singletonFactory.getObject(); this .earlySingletonObjects.put(beanName, singletonObject); this .singletonFactories.remove(beanName); } } } } return (singletonObject != NULL_OBJECT ? singletonObject : null ); }
为什么三级缓存可以解决循环依赖呢?这是因为在bean生命周期的第一步结束后,会将该对象放入三级缓存。这也是无法解决构造器循环依赖的原因。
1 2 3 4 5 6 7 8 9 10 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); } } }
https://blog.csdn.net/u010853261/article/details/77940767
原文作者: NTJD
原文链接: http://yoursite.com/2020/09/24/Spring循环依赖/
版权声明: 转载请注明出处(必须保留作者署名及链接)