首页 > 编程语言 >Spring源码-循环依赖

Spring源码-循环依赖

时间:2022-10-05 14:35:28浏览次数:55  
标签:依赖 Spring beanName value Object bean 源码 singletonObject null

解决循环依赖的思路是将将创建bean分为实例化和初始化,实例化只是为类分配内存,类里面的属性全部都是默认值;初始化是为类的属性设置具体值。所以只能解决set方法注入的循环依赖,不能解决构造函数注入的循环依赖。

一、例子

A.java

public class A {
private B b;

public void printA(){
	System.out.println("this is A");
}

public void setB(B b) {
	this.b = b;
}
}

B.java

public class B {
private A a;

public void printB(){
	System.out.println("this is B");
}

public void setA(A a) {
	this.a = a;
}
}

circle.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:aop="http://www.springframework.org/schema/aop"
	   xmlns:context="http://www.springframework.org/schema/context"
	   xmlns:mvc="http://www.springframework.org/schema/mvc"
	   xmlns:p="http://www.springframework.org/schema/p"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">


	<bean id="a" class="circle.A">
		<property name="b" ref="b"/>
	</bean>


	<bean id="b" class="circle.B">
		<property name="a" ref="a"/>
	</bean>
</beans>

Main.java

public class Main {
public static void main(String[] args) {
	ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("circle.xml");
	A a = applicationContext.getBean(A.class);
	a.printA();
}
}

二、Spring源码跟踪

首先创建A

在AbstractBeanFactory.doGetBean(
String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)调用getSingleton(beanName):

public Object getSingleton(String beanName) {
	return getSingleton(beanName, true);
}

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	// Quick check for existing instance without full singleton lock
	Object singletonObject = this.singletonObjects.get(beanName);
	if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
		singletonObject = this.earlySingletonObjects.get(beanName);
		if (singletonObject == null && allowEarlyReference) {
			synchronized (this.singletonObjects) {
				// Consistent creation of early reference within full singleton lock
				singletonObject = this.singletonObjects.get(beanName);
				if (singletonObject == null) {
					singletonObject = this.earlySingletonObjects.get(beanName);
					if (singletonObject == null) {
						ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
						if (singletonFactory != null) {
							singletonObject = singletonFactory.getObject();
							this.earlySingletonObjects.put(beanName, singletonObject);
							this.singletonFactories.remove(beanName);
						}
					}
				}
			}
		}
	}
	return singletonObject;
}

首先从singletonObjects和earlySingletonObjects中获取bean,能获取就返回,否则从singletonFactories获取对象,对象不为null则调用ObjectFactory.getObject()获取早期暴露的对象并放到earlySingletonObjects中,且从singletonFactories中移除。此时singletonObjects,earlySingletonObjects,singletonFactories都没有对象。

如果能从缓存中获取对象则返回否则调用

getSingleton(beanName, () -> {
					try {
						return createBean(beanName, mbd, args);
					}
					catch (BeansException ex) {
						// Explicitly remove instance from singleton cache: It might have been put there
						// eagerly by the creation process, to allow for circular reference resolution.
						// Also remove any beans that received a temporary reference to the bean.
						destroySingleton(beanName);
						throw ex;
					}
				});

获取对象。

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

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(beanName, "Bean name must not be null");
	synchronized (this.singletonObjects) {
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null) {
			if (this.singletonsCurrentlyInDestruction) {
				throw new BeanCreationNotAllowedException(beanName,
						"Singleton bean creation not allowed while singletons of this factory are in destruction " +
						"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
			}
			beforeSingletonCreation(beanName);
			boolean newSingleton = false;
			boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = new LinkedHashSet<>();
			}
			try {
				singletonObject = singletonFactory.getObject();
				newSingleton = true;
			}
			catch (IllegalStateException ex) {
				// Has the singleton object implicitly appeared in the meantime ->
				// if yes, proceed with it since the exception indicates that state.
				singletonObject = this.singletonObjects.get(beanName);
				if (singletonObject == null) {
					throw ex;
				}
			}
			catch (BeanCreationException ex) {
				if (recordSuppressedExceptions) {
					for (Exception suppressedException : this.suppressedExceptions) {
						ex.addRelatedCause(suppressedException);
					}
				}
				throw ex;
			}
			finally {
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = null;
				}
				afterSingletonCreation(beanName);
			}
			if (newSingleton) {
				addSingleton(beanName, singletonObject);
			}
		}
		return singletonObject;
	}
}

从singletonObjects获取bean,如为null则调用singletonFactory.getObject()创建bean,即调用createBean创建bean。

AbstractAutowireCapableBeanFactory.doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)调用createBeanInstance实例化bean之后,在调用addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));将a放到singletonFactories缓存中且从earlySingletonObjects移除。

此时singletonObjects,earlySingletonObjects,singletonFactories状态为:

继续调用populateBean(beanName, mbd, instanceWrapper);填充a的属性,继续调用applyPropertyValues(beanName, mbd, bw, pvs);填充属性。在applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) 中调用valueResolver.resolveValueIfNecessary(pv, originalValue);解析和填充属性。

BeanDefinitionValueResolver.resolveValueIfNecessary(Object argName, @Nullable Object value)

public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
	// We must check each value to see whether it requires a runtime reference
	// to another bean to be resolved.
	if (value instanceof RuntimeBeanReference) {
		RuntimeBeanReference ref = (RuntimeBeanReference) value;
		return resolveReference(argName, ref);
	}
	else if (value instanceof RuntimeBeanNameReference) {
		String refName = ((RuntimeBeanNameReference) value).getBeanName();
		refName = String.valueOf(doEvaluate(refName));
		if (!this.beanFactory.containsBean(refName)) {
			throw new BeanDefinitionStoreException(
					"Invalid bean name '" + refName + "' in bean reference for " + argName);
		}
		return refName;
	}
	else if (value instanceof BeanDefinitionHolder) {
		// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
		BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
		return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
	}
	else if (value instanceof BeanDefinition) {
		// Resolve plain BeanDefinition, without contained name: use dummy name.
		BeanDefinition bd = (BeanDefinition) value;
		String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
				ObjectUtils.getIdentityHexString(bd);
		return resolveInnerBean(argName, innerBeanName, bd);
	}
	else if (value instanceof DependencyDescriptor) {
		Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
		Object result = this.beanFactory.resolveDependency(
				(DependencyDescriptor) value, this.beanName, autowiredBeanNames, this.typeConverter);
		for (String autowiredBeanName : autowiredBeanNames) {
			if (this.beanFactory.containsBean(autowiredBeanName)) {
				this.beanFactory.registerDependentBean(autowiredBeanName, this.beanName);
			}
		}
		return result;
	}
	else if (value instanceof ManagedArray) {
		// May need to resolve contained runtime references.
		ManagedArray array = (ManagedArray) value;
		Class<?> elementType = array.resolvedElementType;
		if (elementType == null) {
			String elementTypeName = array.getElementTypeName();
			if (StringUtils.hasText(elementTypeName)) {
				try {
					elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
					array.resolvedElementType = elementType;
				}
				catch (Throwable ex) {
					// Improve the message by showing the context.
					throw new BeanCreationException(
							this.beanDefinition.getResourceDescription(), this.beanName,
							"Error resolving array type for " + argName, ex);
				}
			}
			else {
				elementType = Object.class;
			}
		}
		return resolveManagedArray(argName, (List<?>) value, elementType);
	}
	else if (value instanceof ManagedList) {
		// May need to resolve contained runtime references.
		return resolveManagedList(argName, (List<?>) value);
	}
	else if (value instanceof ManagedSet) {
		// May need to resolve contained runtime references.
		return resolveManagedSet(argName, (Set<?>) value);
	}
	else if (value instanceof ManagedMap) {
		// May need to resolve contained runtime references.
		return resolveManagedMap(argName, (Map<?, ?>) value);
	}
	else if (value instanceof ManagedProperties) {
		Properties original = (Properties) value;
		Properties copy = new Properties();
		original.forEach((propKey, propValue) -> {
			if (propKey instanceof TypedStringValue) {
				propKey = evaluate((TypedStringValue) propKey);
			}
			if (propValue instanceof TypedStringValue) {
				propValue = evaluate((TypedStringValue) propValue);
			}
			if (propKey == null || propValue == null) {
				throw new BeanCreationException(
						this.beanDefinition.getResourceDescription(), this.beanName,
						"Error converting Properties key/value pair for " + argName + ": resolved to null");
			}
			copy.put(propKey, propValue);
		});
		return copy;
	}
	else if (value instanceof TypedStringValue) {
		// Convert value to target type here.
		TypedStringValue typedStringValue = (TypedStringValue) value;
		Object valueObject = evaluate(typedStringValue);
		try {
			Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
			if (resolvedTargetType != null) {
				return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
			}
			else {
				return valueObject;
			}
		}
		catch (Throwable ex) {
			// Improve the message by showing the context.
			throw new BeanCreationException(
					this.beanDefinition.getResourceDescription(), this.beanName,
					"Error converting typed String value for " + argName, ex);
		}
	}
	else if (value instanceof NullBean) {
		return null;
	}
	else {
		return evaluate(value);
	}
}

bean a的属性由ref引用,类型是RuntimeBeanReference,调用resolveReference(argName, ref);解析属性。

BeanDefinitionValueResolver.resolveReference(Object argName, RuntimeBeanReference ref)

private Object resolveReference(Object argName, RuntimeBeanReference ref) {
	try {
		Object bean;
		Class<?> beanType = ref.getBeanType();
		if (ref.isToParent()) {
			BeanFactory parent = this.beanFactory.getParentBeanFactory();
			if (parent == null) {
				throw new BeanCreationException(
						this.beanDefinition.getResourceDescription(), this.beanName,
						"Cannot resolve reference to bean " + ref +
								" in parent factory: no parent factory available");
			}
			if (beanType != null) {
				bean = parent.getBean(beanType);
			}
			else {
				bean = parent.getBean(String.valueOf(doEvaluate(ref.getBeanName())));
			}
		}
		else {
			String resolvedName;
			if (beanType != null) {
				NamedBeanHolder<?> namedBean = this.beanFactory.resolveNamedBean(beanType);
				bean = namedBean.getBeanInstance();
				resolvedName = namedBean.getBeanName();
			}
			else {
				resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));
				bean = this.beanFactory.getBean(resolvedName);
			}
			this.beanFactory.registerDependentBean(resolvedName, this.beanName);
		}
		if (bean instanceof NullBean) {
			bean = null;
		}
		return bean;
	}
	catch (BeansException ex) {
		throw new BeanCreationException(
				this.beanDefinition.getResourceDescription(), this.beanName,
				"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
	}
}

获取RuntimeBeanReference的类型。判断是否应从父BeanFactory中获取bean,如果是则从父BeanFactory获取bean。否则判断类型是否为null,若不是调用beanFactory.resolveNamedBean(beanType)通过类型从bean工厂获取bean。如是调用beanFactory.getBean(resolvedName)通过beanName从bean工厂获取bean。

现在进行b的创建:

AbstractAutowireCapableBeanFactory.doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)中调用createBeanInstance(beanName, mbd, args)实例化b之后,在调用addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));将b加入singletonFactories中。

此时singletonObjects,earlySingletonObjects,singletonFactories状态为:

a和b实例化之后的对象都已经放入singletonFactories中,但是其中的属性未赋值。

继续调用populateBean(beanName, mbd, instanceWrapper);进行填充b的属性a。之后的流程和上面a的属性填充一样。调用resolveReference(Object argName, RuntimeBeanReference ref)里的beanFactory.getBean(resolvedName);获取a。

AbstractBeanFactory.doGetBean(String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)中调用getSingleton(beanName):

public Object getSingleton(String beanName) {
	return getSingleton(beanName, true);
}

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	// Quick check for existing instance without full singleton lock
	Object singletonObject = this.singletonObjects.get(beanName);
	if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
		singletonObject = this.earlySingletonObjects.get(beanName);
		if (singletonObject == null && allowEarlyReference) {
			synchronized (this.singletonObjects) {
				// Consistent creation of early reference within full singleton lock
				singletonObject = this.singletonObjects.get(beanName);
				if (singletonObject == null) {
					singletonObject = this.earlySingletonObjects.get(beanName);
					if (singletonObject == null) {
						ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
						if (singletonFactory != null) {
							singletonObject = singletonFactory.getObject();
							this.earlySingletonObjects.put(beanName, singletonObject);
							this.singletonFactories.remove(beanName);
						}
					}
				}
			}
		}
	}
	return singletonObject;
}

此时singletonObjects,earlySingletonObjects没有对象,但是singletonFactories有a,b实例化但未初始化的对象。将a从singletonFactories取出放到earlySingletonObjects中,并从singletonFactories移除。

此时singletonObjects,earlySingletonObjects,singletonFactories状态为:

获取到a之后返回到填充b的属性a的流程中。此时b已经创建完成并初始化完成。

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

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(beanName, "Bean name must not be null");
	synchronized (this.singletonObjects) {
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null) {
			if (this.singletonsCurrentlyInDestruction) {
				throw new BeanCreationNotAllowedException(beanName,
						"Singleton bean creation not allowed while singletons of this factory are in destruction " +
						"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
			}
			beforeSingletonCreation(beanName);
			boolean newSingleton = false;
			boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = new LinkedHashSet<>();
			}
			try {
				singletonObject = singletonFactory.getObject();
				newSingleton = true;
			}
			catch (IllegalStateException ex) {
				// Has the singleton object implicitly appeared in the meantime ->
				// if yes, proceed with it since the exception indicates that state.
				singletonObject = this.singletonObjects.get(beanName);
				if (singletonObject == null) {
					throw ex;
				}
			}
			catch (BeanCreationException ex) {
				if (recordSuppressedExceptions) {
					for (Exception suppressedException : this.suppressedExceptions) {
						ex.addRelatedCause(suppressedException);
					}
				}
				throw ex;
			}
			finally {
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = null;
				}
				afterSingletonCreation(beanName);
			}
			if (newSingleton) {
				addSingleton(beanName, singletonObject);
			}
		}
		return singletonObject;
	}
}

singletonFactory.getObject();创建完b后调用addSingleton(beanName, singletonObject):

DefaultSingletonBeanRegistry.addSingleton(String beanName, Object singletonObject)

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);
	}
}

将b放入singletonObjects中,并从singletonFactories和earlySingletonObjects移除。

此时singletonObjects,earlySingletonObjects,singletonFactories状态为:

之后又返回填充a的属性的流程。此时可以获取属性b并填充属性,之后调用initializeBean完成初始化动作。

a创建完之后在DefaultSingletonBeanRegistry.getSingleton(String beanName, ObjectFactory<?> singletonFactory)

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(beanName, "Bean name must not be null");
	synchronized (this.singletonObjects) {
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null) {
			if (this.singletonsCurrentlyInDestruction) {
				throw new BeanCreationNotAllowedException(beanName,
						"Singleton bean creation not allowed while singletons of this factory are in destruction " +
						"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
			}
			beforeSingletonCreation(beanName);
			boolean newSingleton = false;
			boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = new LinkedHashSet<>();
			}
			try {
				singletonObject = singletonFactory.getObject();
				newSingleton = true;
			}
			catch (IllegalStateException ex) {
				// Has the singleton object implicitly appeared in the meantime ->
				// if yes, proceed with it since the exception indicates that state.
				singletonObject = this.singletonObjects.get(beanName);
				if (singletonObject == null) {
					throw ex;
				}
			}
			catch (BeanCreationException ex) {
				if (recordSuppressedExceptions) {
					for (Exception suppressedException : this.suppressedExceptions) {
						ex.addRelatedCause(suppressedException);
					}
				}
				throw ex;
			}
			finally {
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = null;
				}
				afterSingletonCreation(beanName);
			}
			if (newSingleton) {
				addSingleton(beanName, singletonObject);
			}
		}
		return singletonObject;
	}
}

singletonFactory.getObject()创建完a并初始化后调用addSingleton将a加入singletonObjects。

此时singletonObjects,earlySingletonObjects,singletonFactories状态为:

此时a,b全部创建完成。

标签:依赖,Spring,beanName,value,Object,bean,源码,singletonObject,null
From: https://www.cnblogs.com/shigongp/p/16755438.html

相关文章