Spring循环依赖源码解析

概念区分

  • 实例化(instantiation):创建了一个对象,容器通过反射的方式new了一个对象
  • 初始化(initialization):已经实例化的对象,并完成属性的填充,即初始化 = 实例化 + 属性填充。实例化后的对象就可以直接使用了
  • 提前暴露(early exposure):主要用于解决循环依赖的问题,通过ObjectFactory的方式保存产生Bean的方式,为后续获取Bean提供访问方式

Spring容器初始化Bean的基本流程

核心源码:AbstractAutowireCapableBeanFactory#doCreateBean

  1. 实例化:创建一个Bean对象
  2. 属性填充:为Bean设置属性值和依赖
    • 为了解决循环依赖的问题,Spring会通过提前暴露Bean的方式,提供还未完成初始化的Bean的访问方式
  3. 初始化:初始化阶段涉及的步骤较多
    • 检查Aware接口,调用setXxx()注入特定的依赖
    • 调用BeanPostProcessor前置处理方法
      • ApplicationContextAwareProcessor注入ApplicationContextAware相关的依赖
      • InitDestroyAnnotationBeanPostProcessor调用@PostConstruct注释的初始化方法
    • InitializingBean.afterPropertiesSet()
    • XML中的init-method
    • 调用BeanPostProcessor后置处理方法
  4. 注册销毁相关的回调接口 ,创建DisposableBeanAdapter对象
    • 注册DisposableBean.destroy()接口
    • 注册XML中配置的destroy-method
    • @PreDestroy对应InitDestroyAnnotationBeanPostProcessor.postProcessBeforeDestruction()
  5. 使用Bean
  6. 调用销毁方法,DisposableBeanAdapter.destroy()

三级缓存解决循环依赖的核心源码

因为仅关心Spring解决循环依赖的核心源码,其它源码部分省略:

  • 属性注入的核心源码:AutowiredAnnotationBeanPostProcessor
  • 产生动态代理的核心源码:AnnotationAwareAspectJAutoProxyCreator

DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory<?> singletonFactory)

继承关系DefaultSingletonBeanRegistry <- AbstractBeanFactory <- AbstractAutowireCapableBeanFactory

// DefaultSingletonBeanRegistry

	/** 用于存储已经初始化完毕的Bean */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/** 用于存储Bean对应的ObjectFactory */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	/** 用于存储已经实例化,属性未填充的Bean */
	private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

	// 将初始化完毕的Bean加入singletonObjects,并从singletonFactories和earlySingletonObjects中移除
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}

	(\*\*)
	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // 先从singletonObjects获取Bean
		Object singletonObject = this.singletonObjects.get(beanName);
        //Bean未初始化完成,且Bean还在创建中
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
                // 从earlySingletonObjects中获取Bean
				singletonObject = this.earlySingletonObjects.get(beanName);
                // 未获取到Bean,且allowEarlyReference == true
				if (singletonObject == null && allowEarlyReference) {
                    // 从singletonFactories获取Bean
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
                        // 获取Bean
						singletonObject = singletonFactory.getObject();
                        // 将Bean放置到earlySingletonObjects
						this.earlySingletonObjects.put(beanName, singletonObject);
                        // 从singletonFactories中移除Bean
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

	//核心就是调用singletonFactory获取Bean
	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		synchronized (this.singletonObjects) {
            //先从singletonObjects中取
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				// ......
				try {
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// ......
				}
				catch (BeanCreationException ex) {
					// ......
				}
				finally {
					// ......
				}
				if (newSingleton) {
                    // 将生成的Bean添加到singletonObjects中
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

	// 将beanName和对应的singletonFactory存入singletonFactories
	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		synchronized (this.singletonObjects) {
            // 如果beanName在singletonObjects没有已经初始化完成的Bean,就保存singletonFactory到singletonFactories
			if (!this.singletonObjects.containsKey(beanName)) {
				this.singletonFactories.put(beanName, singletonFactory);
				this.earlySingletonObjects.remove(beanName); //从earlySingletonObjects中移除Bean
				this.registeredSingletons.add(beanName); //表示Bean已经注册
			}
		}
	}

AbstractBeanFactory#doGetBean

// AbstractBeanFactory

	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

		// 先从三级缓存的Map中获取数据
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			//......
		}

		else {
			//......

			try {
				//Bean不在缓存中

				// 创建单例的Bean实例
				if (mbd.isSingleton()) {
                    // 实际上就是调用createBean获取Bean
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							//......
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					// 创建prototype的Bean实例
					// ......
				}

				else {
					//其他scope的处理逻辑
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// ......
		return (T) bean;
	}
  • getSingleton(String beanName, boolean allowEarlyReference) :从三级缓存中获取Bean
  • getSingleton(String beanName, ObjectFactory<?> singletonFactory):调用createBean()创建Bean,并添加到singletonObjects

AbstractAutowireCapableBeanFactory#doCreateBean

//AbstractAutowireCapableBeanFactory
	
	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		//创建Bean实例
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		//判断是否需要早期暴露Bean,用于解决循环依赖
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			// (\*\*) 将beanName对应的ObjectFactory存入singletonFactories,再次获取Bean时,直接从singletonFactories中获取
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
            //填充@Autowired属性
			populateBean(beanName, mbd, instanceWrapper);
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			//.......
		}
        
        // 解决代理对象的依赖问题
        if (earlySingletonExposure) {
            //如果Bean被AOP代理,这里就会从earlySingletonObjects中获取到代理对象
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
                    // earlySingletonReference -> exposedObject
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                	// .....
                }
			}
		}

       //......

		return exposedObject;
	}

	//用于解决循环依赖的场景,返回bean
	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
        // 获取要返回的对象
		Object exposedObject = bean;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
                // SmartInstantiationAwareBeanPostProcessor获取早期的Bean
                // AnnotationAwareAspectJAutoProxyCreator.getEarlyBeanReference会返回代理对象
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		return exposedObject;
	}

无AOP循环依赖解决示例

以循环依赖的示例串联整个过程:

@Component
public class Teacher {
    @Autowired
    Student student;

    public Teacher() {
        System.out.println("Teacher init:" + student);
    }
}
@Component
public class Student {
    @Autowired
    Teacher teacher;

    public Student() {
        System.out.println("Student init:" + teacher);
    }
}

以容器先创建Student,再创建Teacher为例。为了简化分析过程,仅围绕和循环依赖的内容展开:

  1. 获取Student实例:AbstractBeanFactory#getBean(String) -> AbstractBeanFactory#doGetBean
    1. 因为容器中目前没有Student实例,创建Student实例:instanceWrapper = createBeanInstance(beanName, mbd, args);
  2. 提前暴露Student实例:
    • 计算是否需要提前暴露Bean实例:boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
    • DefaultSingletonBeanRegistry#addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));:将beanName==student() -> getEarlyBeanReference(beanName, mbd, bean)ObjectFactory添加到singletonFactories
  3. Student实例属性填充:AbstractAutowireCapableBeanFactory#populateBean
  4. 获取Teacher实例:DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory)
    1. 因为容器中目前没有Teacher实例,创建Teacher实例:instanceWrapper = createBeanInstance(beanName, mbd, args);
  5. 提前暴露Teacher实例
    • 计算是否需要提前暴露Bean实例:boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
    • DefaultSingletonBeanRegistry#addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));:将beanName==teacher() -> getEarlyBeanReference(beanName, mbd, bean)的ObjectFactory添加到singletonFactories中;
  6. Teacher实例属性填充:AbstractAutowireCapableBeanFactory#populateBean
  7. 获取Student实例:AbstractBeanFactory#getBean(String) -> AbstractBeanFactory#doGetBean
    1. 因为singletonFactories中已有Student实例,直接获取到Student实例:(**)DefaultSingletonBeanRegistry#getSingleton(String) -> DefaultSingletonBeanRegistry#getSingleton(String, true):
      1. 此时allowEarlyReference==true,且仅有singletonFactories中保存了student对应的ObjectFactory,所以会调用singletonFacotry.getObject()获取Student实例,
      2. 而这实际通过匿名内部类的方式调用了() -> getEarlyBeanReference(beanName, mbd, bean),获取到对应的Student的实例对象。(注意这里的Student对象还没有Teacher属性,即还未完成属性填充)
      3. (**)获取的Student实例后,被放置到earlySingletonObjects中,并且从singletonFactories中移除student的ObjectFactory;
  8. Teacher完成属性填充
  9. 因为earlySingletonExposure==true,Teacher实例暴露的后续逻辑:
    1. 执行DefaultSingletonBeanRegistry#getSingleton(String, boolean):因为allowEarlyReference == false,执行完逻辑,返回一个null
    2. 因为earlySingletonReference==null,不会替换初始化完毕的Teacher的实例
  10. Teacher实例初始化完成
  11. Student实例完成属性填充
  12. 因为earlySingletonExposure == true,Student实例暴露的后续逻辑:
    1. 这时earlySingletonObjects已经保存了student的对象,所以直接返回
    2. 执行exposedObject = earlySingletonReference,此时exposedObject和earlySingletonReference本来就是一个对象,所以不影响
  13. Student实例完成初始化

第7步,Teacher完成属性填充后,Student还未填充属性:

第11步,Student完成属性填充

有AOP循环依赖解决示例

现在为Student#learn()添加一个切面

@Aspect
@Component
public class MyAspect {
    @Pointcut("execution(* com.ldh.circular.dependency.entity.Student.learn(..))")
    public void pointcut() {
    }

    @Before("pointcut()")
    public void beforeAdvice(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        System.out.println(String.format("在方法:%s之前,前置前面逻辑", signature.getName()));
    }
}
  1. 获取Student实例:AbstractBeanFactory#getBean(String) -> AbstractBeanFactory#doGetBean
    1. 因为容器中目前没有Student实例,创建Student实例:instanceWrapper = createBeanInstance(beanName, mbd, args);。注意:这里仅返回了Student的单例,并不是代理对象
  2. 提前暴露Student实例:
    • 计算是否需要提前暴露Bean实例:boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
    • DefaultSingletonBeanRegistry#addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));:将beanName==student() -> getEarlyBeanReference(beanName, mbd, bean)ObjectFactory添加到singletonFactories
  3. Student实例属性填充:AbstractAutowireCapableBeanFactory#populateBean
  4. 获取Teacher实例:DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory)
    1. 因为容器中目前没有Teacher实例,创建Teacher实例:instanceWrapper = createBeanInstance(beanName, mbd, args);
  5. 提前暴露Teacher实例
    • 计算是否需要提前暴露Bean实例:boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
    • DefaultSingletonBeanRegistry#addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));:将beanName==teacher() -> getEarlyBeanReference(beanName, mbd, bean)的ObjectFactory添加到singletonFactories中;
  6. Teacher实例属性填充:AbstractAutowireCapableBeanFactory#populateBean
  7. 获取Student实例:AbstractBeanFactory#getBean(String) -> AbstractBeanFactory#doGetBean
    1. 因为singletonFactories中已有Student实例,直接获取到Student实例:(**)DefaultSingletonBeanRegistry#getSingleton(String) -> DefaultSingletonBeanRegistry#getSingleton(String, true):
      1. 此时allowEarlyReference==true,且仅有singletonFactories中保存了student对应的ObjectFactory,所以会调用singletonFacotry.getObject()获取Student实例,
      2. (**)而这实际通过匿名内部类的方式调用了() -> getEarlyBeanReference(beanName, mbd, bean),获取到对应的Student的代理对象。(注意这里的Student代理对象还没有Teacher属性,即还未完成属性填充)
      3. (**)获取的Student的代理对象后,被放置到earlySingletonObjects中,并且从singletonFactories中移除student的ObjectFactory;
  8. Teacher完成属性填充
  9. 因为earlySingletonExposure==true,Teacher实例暴露的后续逻辑:
    1. 执行DefaultSingletonBeanRegistry#getSingleton(String, boolean):因为allowEarlyReference == false,执行完逻辑,返回一个null
    2. 因为earlySingletonReference==null,不会替换初始化完毕的Teacher的实例
  10. Teacher实例初始化完成
  11. Student实例完成属性填充
  12. 因为earlySingletonExposure == true,Student实例暴露的后续逻辑:
    1. 这时earlySingletonObjects已经保存了Student的代理对象,所以直接返回
    2. 执行exposedObject = earlySingletonReference,此时Student的代理对象设置成exposedObject
  13. Student实例完成初始化

执行完第1步,Student实例并不是一个代理对象:

执行完7.2步,已经生成Student的代理对象

执行完第8步,看以看到,Teacher实例已经注入了Student的代理对象:

执行完第11步,Student实例完成属性填充后如下所示,可以看到Teacher中注入的已经是代理对象,而Student实例并不是被代理。

有无AOP的区别

有无AOP的区别在于是否会执行AnnotationAwareAspectJAutoProxyCreator#getEarlyBeanReference生成Bean的动态代理对象,其它的流程基本是一致的。

为什么是三级缓存而不是二级缓存?

实际上如果不考虑动态代理的情况下,只要将未完成初始化的实例保存到一个缓存,然后,在需要注入Bean的时候,直接注入即可。

但是,因为要支持动态代理,且Spring一开始实例化对象时,并不会直接返回一个代理对象(PS:目前我也不清楚原因~~~)。因此,没法提前暴露一个未代理的对象到一个缓存中,Spring采用ObjectFactory的形式暴露了Bean的访问方式。后续,需要注入这个Bean时,Spring通过ObjectFactory#getObject()的方式获取到所需的Bean(如果Bean加了动态代理,内部会通过AnnotationAwareAspectJAutoProxyCreator#getEarlyBeanReference的方式获取代理对象)。所以,Spring需要提供三级缓存:

  1. singletonObjects:保存已经初始化完毕的Bean
  2. singletonFactories:保存需要提前暴露,但是目前没法直接返回的Bean,通过ObjectFactory的形式封装
  3. earlySingletonObjects:保存通过ObjectFactory#getObject()获取的Bean

参考:

posted on   DaydayupLiu  阅读(269)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

统计

点击右上角即可分享
微信分享提示