fixed concurrency issue in TypedStringValue, showing for nested typed Maps in prototype beans (SPR-7398); optimized building of keyed arg names in BeanDefinitionValueResolver
This commit is contained in:
parent
bd4f4d0d30
commit
c3a639f07d
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -38,7 +38,7 @@ public class TypedStringValue implements BeanMetadataElement {
|
||||||
|
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
private Object targetType;
|
private volatile Object targetType;
|
||||||
|
|
||||||
private Object source;
|
private Object source;
|
||||||
|
|
||||||
|
|
@ -110,10 +110,11 @@ public class TypedStringValue implements BeanMetadataElement {
|
||||||
* Return the type to convert to.
|
* Return the type to convert to.
|
||||||
*/
|
*/
|
||||||
public Class getTargetType() {
|
public Class getTargetType() {
|
||||||
if (!(this.targetType instanceof Class)) {
|
Object targetTypeValue = this.targetType;
|
||||||
|
if (!(targetTypeValue instanceof Class)) {
|
||||||
throw new IllegalStateException("Typed String value does not carry a resolved target type");
|
throw new IllegalStateException("Typed String value does not carry a resolved target type");
|
||||||
}
|
}
|
||||||
return (Class) this.targetType;
|
return (Class) targetTypeValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -128,11 +129,12 @@ public class TypedStringValue implements BeanMetadataElement {
|
||||||
* Return the type to convert to.
|
* Return the type to convert to.
|
||||||
*/
|
*/
|
||||||
public String getTargetTypeName() {
|
public String getTargetTypeName() {
|
||||||
if (this.targetType instanceof Class) {
|
Object targetTypeValue = this.targetType;
|
||||||
return ((Class) this.targetType).getName();
|
if (targetTypeValue instanceof Class) {
|
||||||
|
return ((Class) targetTypeValue).getName();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return (String) this.targetType;
|
return (String) targetTypeValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -338,9 +338,7 @@ class BeanDefinitionValueResolver {
|
||||||
Object resolved = Array.newInstance(elementType, ml.size());
|
Object resolved = Array.newInstance(elementType, ml.size());
|
||||||
for (int i = 0; i < ml.size(); i++) {
|
for (int i = 0; i < ml.size(); i++) {
|
||||||
Array.set(resolved, i,
|
Array.set(resolved, i,
|
||||||
resolveValueIfNecessary(
|
resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
|
||||||
argName + " with key " + BeanWrapper.PROPERTY_KEY_PREFIX + i + BeanWrapper.PROPERTY_KEY_SUFFIX,
|
|
||||||
ml.get(i)));
|
|
||||||
}
|
}
|
||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
|
|
@ -352,9 +350,7 @@ class BeanDefinitionValueResolver {
|
||||||
List<Object> resolved = new ArrayList<Object>(ml.size());
|
List<Object> resolved = new ArrayList<Object>(ml.size());
|
||||||
for (int i = 0; i < ml.size(); i++) {
|
for (int i = 0; i < ml.size(); i++) {
|
||||||
resolved.add(
|
resolved.add(
|
||||||
resolveValueIfNecessary(
|
resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
|
||||||
argName + " with key " + BeanWrapper.PROPERTY_KEY_PREFIX + i + BeanWrapper.PROPERTY_KEY_SUFFIX,
|
|
||||||
ml.get(i)));
|
|
||||||
}
|
}
|
||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
|
|
@ -366,8 +362,7 @@ class BeanDefinitionValueResolver {
|
||||||
Set<Object> resolved = new LinkedHashSet<Object>(ms.size());
|
Set<Object> resolved = new LinkedHashSet<Object>(ms.size());
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Object m : ms) {
|
for (Object m : ms) {
|
||||||
resolved.add(resolveValueIfNecessary(
|
resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), m));
|
||||||
argName + " with key " + BeanWrapper.PROPERTY_KEY_PREFIX + i + BeanWrapper.PROPERTY_KEY_SUFFIX, m));
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return resolved;
|
return resolved;
|
||||||
|
|
@ -381,11 +376,32 @@ class BeanDefinitionValueResolver {
|
||||||
for (Map.Entry entry : mm.entrySet()) {
|
for (Map.Entry entry : mm.entrySet()) {
|
||||||
Object resolvedKey = resolveValueIfNecessary(argName, entry.getKey());
|
Object resolvedKey = resolveValueIfNecessary(argName, entry.getKey());
|
||||||
Object resolvedValue = resolveValueIfNecessary(
|
Object resolvedValue = resolveValueIfNecessary(
|
||||||
argName + " with key " + BeanWrapper.PROPERTY_KEY_PREFIX + entry.getKey() +
|
new KeyedArgName(argName, entry.getKey()), entry.getValue());
|
||||||
BeanWrapper.PROPERTY_KEY_SUFFIX, entry.getValue());
|
|
||||||
resolved.put(resolvedKey, resolvedValue);
|
resolved.put(resolvedKey, resolvedValue);
|
||||||
}
|
}
|
||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holder class used for delayed toString building.
|
||||||
|
*/
|
||||||
|
private static class KeyedArgName {
|
||||||
|
|
||||||
|
private final Object argName;
|
||||||
|
|
||||||
|
private final Object key;
|
||||||
|
|
||||||
|
public KeyedArgName(Object argName, Object key) {
|
||||||
|
this.argName = argName;
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.argName + " with key " + BeanWrapper.PROPERTY_KEY_PREFIX +
|
||||||
|
this.key + BeanWrapper.PROPERTY_KEY_SUFFIX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue