假设有两个类A和B
B是A的成员变量,A也是B的成员变量。
假设类A的bean为a,类B的bean为b。且IOC容器先处理A。
熟悉Spring容器初始化的同学,应该都知道,容器初始化的过程中,bean的创建是如下触发的:
getBean
的时候发现不存在,就去 createBean
。
bean的创建是在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
完成的。
doCreateBean
大致可以分为三步:
1、实例化bean:createBeanInstance
2、填充属性:populateBean
3、初始化bean:initializeBean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;// 实例化beanif (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}......boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {// 放入3级缓存addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}......try {// 填充属性populateBean(beanName, mbd, instanceWrapper);// 初始化beanexposedObject = initializeBean(beanName, exposedObject, mbd);}...... return exposedObject;}
其中第三步,只是Spring框架提供的 InitializingBean
接口的扩展,用于设置完properties之后做一些动作,对循环依赖没有影响。
循环依赖的处理只发生在第一步和第二步。
从以上代码可以看到,当A类的一个单例对象a被实例化之后,被立即放在了3级缓存内,具体的代码如下:
/*** Add the given singleton factory for building the specified singleton* if necessary.* <p>To be called for eager registration of singletons, e.g. to be able to* resolve circular references.* @param beanName the name of the bean* @param singletonFactory the factory for the singleton object*/protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {// 放入3级缓存this.singletonFactories.put(beanName, singletonFactory);// 从2级缓存中移除(确保2级缓存没有)this.earlySingletonObjects.remove(beanName);// 标记这个bean已经创建过this.registeredSingletons.add(beanName);}}}
在给a设置属性B的时候,去对B进行 getBean
,发现不存在,也会对B进行 createBean
。
类B的对象b,在实例化之后,也会进行属性的设置,会对类A进行 getBean
,这部分就有了差异。
@SuppressWarnings("unchecked")protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {String beanName = transformedBeanName(name);Object beanInstance;// 这里去获取A的单例bean// Eagerly check singleton cache for manually registered singletons.Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.trace("Returning cached instance of singleton bean '" + beanName + "'");}}beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);}
getSingleton
的代码如下:
/*** Return the (raw) singleton object registered under the given name.* <p>Checks already instantiated singletons and also allows for an early* reference to a currently created singleton (resolving a circular reference).* @param beanName the name of the bean to look for* @param allowEarlyReference whether early references should be created or not* @return the registered singleton object, or {@code null} if none found*/@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {// Quick check for existing instance without full singleton lock// 从1级缓存拿Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {// 从2级缓存拿singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {synchronized (this.singletonObjects) {// Consistent creation of early reference within full singleton locksingletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null) {// 从3级缓存拿ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {singletonObject = singletonFactory.getObject();// 放入2级缓存this.earlySingletonObjects.put(beanName, singletonObject);// 从3级缓存中移除this.singletonFactories.remove(beanName);}}}}}}return singletonObject;}
因为前面类A执行 doCreateBean
的时候,已经放进了3级缓存,所以b在设置属性的时候,是能拿得到a的。
这里的拿到的a还仅仅是执行了实例化的,并没有设置完属性。
b在执行完第二步设置属性,第三步初始化之后,又返回到a的第二步设置属性,第三步初始化。
至此,类A的对象a和类B的对象b,都已经创建成功。
最终总结流程图如下: