Resolve nested placeholders via PropertyResolver

Prior to this change, PropertySourcesPropertyResolver (and therefore
all AbstractEnvironment) implementations failed to resolve nested
placeholders as in the following example:

    p1=v1
    p2=v2
    p3=${v1}:{$v2}

Calls to PropertySource#getProperty for keys 'p1' and 'v1' would
successfully return their respective values, but for 'p3' the return
value would be the unresolved placeholders. This behavior is
inconsistent with that of PropertyPlaceholderConfigurer.

PropertySourcesPropertyResolver #getProperty variants now resolve any
nested placeholders recursively, throwing IllegalArgumentException for
any unresolvable placeholders (as is the default behavior for
PropertyPlaceholderConfigurer). See SPR-9569 for an enhancement that
will intoduce an 'ignoreUnresolvablePlaceholders' switch to make this
behavior configurable.

This commit also improves error output in
PropertyPlaceholderHelper#parseStringValue by including the original
string in which an unresolvable placeholder was found.

Issue: SPR-9473, SPR-9569
This commit is contained in:
Chris Beams
2012-07-05 15:45:35 +02:00
parent b9786ccaca
commit 2ec7834124
3 changed files with 44 additions and 9 deletions

View File

@@ -72,6 +72,9 @@ public class PropertySourcesPropertyResolver extends AbstractPropertyResolver {
Object value;
if ((value = propertySource.getProperty(key)) != null) {
Class<?> valueType = value.getClass();
if (String.class.equals(valueType)) {
value = this.resolveRequiredPlaceholders((String) value);
}
if (debugEnabled) {
logger.debug(
format("Found key '%s' in [%s] with type [%s] and value '%s'",

View File

@@ -171,7 +171,8 @@ public class PropertyPlaceholderHelper {
startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
}
else {
throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "'");
throw new IllegalArgumentException("Could not resolve placeholder '" +
placeholder + "'" + " in string value [" + strVal + "]");
}
visitedPlaceholders.remove(originalPlaceholder);