public Object resolveValueIfNecessary(Object argName,
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 ref = ((RuntimeBeanNameReference) value).getBeanName();
if (!this.beanFactory.containsBean(ref)) {
throw new BeanDefinitionStoreException(
"Invalid bean name '" + ref + "' in bean reference for " + argName);
}
return ref;
}
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;
return resolveInnerBean(argName, "(inner bean)", bd);
}
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();
for (Iterator it = original.entrySet().iterator(); it.hasNext();) {
Map.Entry propEntry = (Map.Entry) it.next();
Object propKey = propEntry.getKey();
Object propValue = propEntry.getValue();
if (propKey instanceof TypedStringValue) {
propKey = ((TypedStringValue) propKey).getValue();
}
if (propValue instanceof TypedStringValue) {
propValue = ((TypedStringValue) propValue).getValue();
}
copy.put(propKey, propValue);
}
return copy;
}
else if (value instanceof TypedStringValue) {
// Convert value to target type here.
TypedStringValue typedStringValue = (TypedStringValue) value;
try {
Class resolvedTargetType = resolveTargetType(typedStringValue);
if (resolvedTargetType != null) {
return this.typeConverter.convertIfNecessary(typedStringValue.getValue(), resolvedTargetType);
}
else {
// No target type specified - no conversion necessary...
return typedStringValue.getValue();
}
}
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 {
// No need to resolve value...
return value;
}
}
Given a PropertyValue, return a value, resolving any references to other
beans in the factory if necessary. The value could be:
- A BeanDefinition, which leads to the creation of a corresponding
new bean instance. Singleton flags and names of such "inner beans"
are always ignored: Inner beans are anonymous prototypes.
- A RuntimeBeanReference, which must be resolved.
- A ManagedList. This is a special collection that may contain
RuntimeBeanReferences or Collections that will need to be resolved.
- A ManagedSet. May also contain RuntimeBeanReferences or
Collections that will need to be resolved.
- A ManagedMap. In this case the value may be a RuntimeBeanReference
or Collection that will need to be resolved.
- An ordinary object or
null, in which case it's left alone. |