经过上一篇文章 Spring源码学习【四】依赖注入过程 对Spring依赖注入过程的分析,我们知道了在注入Property时会创建一个深拷贝副本,将这个副本持有的Property注入到Bean中,在创建的过程中会使用BeanDefinitionValueResolver解析PropertyValue,代码如下:
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
这里调用了BeanDefinitionValueResolver的resolveValueIfNecessary方法,在这个方法中,将BeanDefinition中定义的Property解析为真正的对象,代码如下:
class BeanDefinitionValueResolver {
...
@Nullable
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
// 解析Bean引用
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
return resolveReference(argName, ref);
}
// 解析Bean name引用
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;
}
// 解析BeanDefinition,包含Bean name、aliases等
else if (value instanceof BeanDefinitionHolder) {
BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
}
// 解析原始BeanDefinition
else if (value instanceof BeanDefinition) {
BeanDefinition bd = (BeanDefinition) value;
String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(bd);
return resolveInnerBean(argName, innerBeanName, bd);
}
// 解析Array
else if (value instanceof ManagedArray) {
ManagedArray array = (ManagedArray) value;
Class<?> elementType = array.resolvedElementType;
// 如果未指定列表元素类型,则通过元素类型名获取元素类型或认为是Object类型
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) {
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);
}
// 解析List
else if (value instanceof ManagedList) {
return resolveManagedList(argName, (List<?>) value);
}
// 解析Set
else if (value instanceof ManagedSet) {
// May need to resolve contained runtime references.
return resolveManagedSet(argName, (Set<?>) value);
}
// 解析Map
else if (value instanceof ManagedMap) {
// May need to resolve contained runtime references.
return resolveManagedMap(argName, (Map<?, ?>) value);
}
// 解析Properties
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) {
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) {
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);
}
}
}
从上面的代码中可以看到,最终会返回一个解析好的真实对象,我们仍然以集合类型Property看一下具体的解析方法,代码如下:
class BeanDefinitionValueResolver {
...
/**
* 解析ManagedArray,可能存在Bean引用的情况
*/
private Object resolveManagedArray(Object argName, List<?> ml, Class<?> elementType) {
Object resolved = Array.newInstance(elementType, ml.size());
for (int i = 0; i < ml.size(); i++) {
Array.set(resolved, i,resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
}
return resolved;
}
/**
* 解析ManagedList
*/
private List<?> resolveManagedList(Object argName, List<?> ml) {
List<Object> resolved = new ArrayList<>(ml.size());
for (int i = 0; i < ml.size(); i++) {
resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
}
return resolved;
}
/**
* 解析ManagedSet
*/
private Set<?> resolveManagedSet(Object argName, Set<?> ms) {
Set<Object> resolved = new LinkedHashSet<>(ms.size());
int i = 0;
for (Object m : ms) {
resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), m));
i++;
}
return resolved;
}
/**
* 解析ManagedMap
*/
private Map<?, ?> resolveManagedMap(Object argName, Map<?, ?> mm) {
Map<Object, Object> resolved = new LinkedHashMap<>(mm.size());
mm.forEach((key, value) -> {
Object resolvedKey = resolveValueIfNecessary(argName, key);
Object resolvedValue = resolveValueIfNecessary(new KeyedArgName(argName, key), value);
resolved.put(resolvedKey, resolvedValue);
});
return resolved;
}
}
从上面的代码中我们看到,最终创建了相应的集合数据结构,并将集合元素添加到了集合中,这样BeanDefinition中定义的Property就解析为一个真正的对象了,下面就可以进行依赖的注入了。