Fix @PropertySource bug with multiple values
Prior to this commit, specifying a named @PropertySource with multiple
values would not work as expected. e.g.:
@PropertySource(
name = "ps",
value = { "classpath:a.properties", "classpath:b.properties" })
In this scenario, the implementation would register a.properties with
the name "ps", and subsequently register b.properties with the name
"ps", overwriting the entry for a.properties.
To fix this behavior, a CompositePropertySource type has been introduced
which accepts a single name and a set of PropertySource objects to
iterate over. ConfigurationClassParser's @PropertySource parsing routine
has been updated to use this composite approach when necessary, i.e.
when both an explicit name and more than one location have been
specified.
Note that if no explicit name is specified, the generated property
source names are enough to distinguish the instances and avoid
overwriting each other; this is why the composite wrapper is not used
in these cases.
Issue: SPR-9127
This commit is contained in:
65
org.springframework.core/src/main/java/org/springframework/core/env/CompositePropertySource.java
vendored
Normal file
65
org.springframework.core/src/main/java/org/springframework/core/env/CompositePropertySource.java
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.core.env;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Composite {@link PropertySource} implementation that iterates over a set of
|
||||
* {@link PropertySource} instances. Necessary in cases where multiple property sources
|
||||
* share the same name, e.g. when multiple values are supplied to {@code @PropertySource}.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1.1
|
||||
*/
|
||||
public class CompositePropertySource extends PropertySource<Object> {
|
||||
|
||||
private Set<PropertySource<?>> propertySources = new LinkedHashSet<PropertySource<?>>();
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code CompositePropertySource}.
|
||||
*
|
||||
* @param name the name of the property source
|
||||
*/
|
||||
public CompositePropertySource(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getProperty(String name) {
|
||||
for (PropertySource<?> propertySource : this.propertySources) {
|
||||
Object candidate = propertySource.getProperty(name);
|
||||
if (candidate != null) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addPropertySource(PropertySource<?> propertySource) {
|
||||
this.propertySources.add(propertySource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s [name='%s', propertySources=%s]",
|
||||
this.getClass().getSimpleName(), this.name, this.propertySources);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user