SpringBean / 三级缓存

Bean生命周期

  1. Bean实例化
  2. Bean填充属性(给属性赋值)
  3. Bean初始化化(比如准备资源文件)
  4. Bean销毁(释放资源—对象从内存销毁)

SpringBean / 三级缓存_第1张图片
三级缓存

循环依赖:A -> B ,B -> A
初始化时循环依赖借助三级缓存解决。利用半成品对象实现依赖,等初始化完成后就依赖了完整的对象。

SpringBean在实例化完成后、会放进三级缓存供其他对象使用(未初始化和设置属性的半成品)。
SpringBean / 三级缓存_第2张图片
获取bean时、依次从一级缓存、二级缓存、三级缓存拿,可以看到从三级缓存拿到后会直接放进二级缓存(应对AOP情况下的循环依赖)


	@Nullable
	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;
	}

为什么不是二级缓存

每次执行singleFactory.getObject()方法又会产生新的代理对象,假设这里只有一级和三级缓存的话,我每次从三级缓存中拿到singleFactory对象,执行getObject()方法又会产生新的代理对象,这是不行的,因为对象是单例的。

你可能感兴趣的:(java)