Revised @PropertySource parsing for consistent PropertySource naming, avoiding accidental overriding by name
Issue: SPR-11637
(cherry picked from commit ab24dda)
This commit is contained in:
@@ -116,7 +116,8 @@ class ConfigurationClassParser {
|
||||
|
||||
private final Map<String, ConfigurationClass> knownSuperclasses = new HashMap<String, ConfigurationClass>();
|
||||
|
||||
private final MultiValueMap<String, PropertySource<?>> propertySources = new LinkedMultiValueMap<String, PropertySource<?>>();
|
||||
private final MultiValueMap<String, ResourcePropertySource> propertySources =
|
||||
new LinkedMultiValueMap<String, ResourcePropertySource>();
|
||||
|
||||
private final ImportStack importStack = new ImportStack();
|
||||
|
||||
@@ -310,16 +311,10 @@ class ConfigurationClassParser {
|
||||
}
|
||||
for (String location : locations) {
|
||||
try {
|
||||
Resource resource = this.resourceLoader.getResource(
|
||||
this.environment.resolveRequiredPlaceholders(location));
|
||||
if (!StringUtils.hasText(name) || this.propertySources.containsKey(name)) {
|
||||
// We need to ensure unique names when the property source will ultimately end up in a composite
|
||||
ResourcePropertySource ps = new ResourcePropertySource(resource);
|
||||
this.propertySources.add((StringUtils.hasText(name) ? name : ps.getName()), ps);
|
||||
}
|
||||
else {
|
||||
this.propertySources.add(name, new ResourcePropertySource(name, resource));
|
||||
}
|
||||
String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
|
||||
Resource resource = this.resourceLoader.getResource(resolvedLocation);
|
||||
ResourcePropertySource ps = new ResourcePropertySource(resource);
|
||||
this.propertySources.add((StringUtils.hasText(name) ? name : ps.getName()), ps);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// from resolveRequiredPlaceholders
|
||||
@@ -482,15 +477,15 @@ class ConfigurationClassParser {
|
||||
|
||||
public List<PropertySource<?>> getPropertySources() {
|
||||
List<PropertySource<?>> propertySources = new LinkedList<PropertySource<?>>();
|
||||
for (Map.Entry<String, List<PropertySource<?>>> entry : this.propertySources.entrySet()) {
|
||||
for (Map.Entry<String, List<ResourcePropertySource>> entry : this.propertySources.entrySet()) {
|
||||
propertySources.add(0, collatePropertySources(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
return propertySources;
|
||||
}
|
||||
|
||||
private PropertySource<?> collatePropertySources(String name, List<PropertySource<?>> propertySources) {
|
||||
private PropertySource<?> collatePropertySources(String name, List<ResourcePropertySource> propertySources) {
|
||||
if (propertySources.size() == 1) {
|
||||
return propertySources.get(0);
|
||||
return propertySources.get(0).withName(name);
|
||||
}
|
||||
CompositePropertySource result = new CompositePropertySource(name);
|
||||
for (int i = propertySources.size() - 1; i >= 0; i--) {
|
||||
|
||||
@@ -124,9 +124,14 @@ public class PropertySourceAnnotationTests {
|
||||
System.clearProperty("path.to.properties");
|
||||
}
|
||||
|
||||
/**
|
||||
* SPR-10820
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void withEmptyResourceLocations() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ConfigWithEmptyResourceLocations.class);
|
||||
ctx.refresh();
|
||||
}
|
||||
|
||||
// SPR-10820
|
||||
@Test
|
||||
public void orderingWithAndWithoutNameAndMultipleResourceLocations() {
|
||||
// p2 should 'win' as it was registered last
|
||||
@@ -136,13 +141,6 @@ public class PropertySourceAnnotationTests {
|
||||
assertThat(ctxWithName.getEnvironment().getProperty("testbean.name"), equalTo("p2TestBean"));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void withEmptyResourceLocations() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ConfigWithEmptyResourceLocations.class);
|
||||
ctx.refresh();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withNameAndMultipleResourceLocations() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithNameAndMultipleResourceLocations.class);
|
||||
@@ -170,6 +168,15 @@ public class PropertySourceAnnotationTests {
|
||||
assertThat(ctx.getEnvironment().getProperty("testbean.name"), equalTo("p2TestBean"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withNamedPropertySources() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithNamedPropertySources.class);
|
||||
assertThat(ctx.getEnvironment().containsProperty("from.p1"), is(true));
|
||||
assertThat(ctx.getEnvironment().containsProperty("from.p2"), is(true));
|
||||
// p2 should 'win' as it was registered last
|
||||
assertThat(ctx.getEnvironment().getProperty("testbean.name"), equalTo("p2TestBean"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withMissingPropertySource() {
|
||||
thrown.expect(BeanDefinitionStoreException.class);
|
||||
@@ -269,8 +276,8 @@ public class PropertySourceAnnotationTests {
|
||||
|
||||
@Configuration
|
||||
@PropertySources({
|
||||
@PropertySource(name = "psName", value="classpath:org/springframework/context/annotation/p1.properties"),
|
||||
@PropertySource(name = "psName", value="classpath:org/springframework/context/annotation/p2.properties")
|
||||
@PropertySource("classpath:org/springframework/context/annotation/p1.properties"),
|
||||
@PropertySource("classpath:org/springframework/context/annotation/p2.properties"),
|
||||
})
|
||||
static class ConfigWithPropertySources {
|
||||
}
|
||||
@@ -278,9 +285,18 @@ public class PropertySourceAnnotationTests {
|
||||
|
||||
@Configuration
|
||||
@PropertySources({
|
||||
@PropertySource(name = "psName", value="classpath:org/springframework/context/annotation/p1.properties"),
|
||||
@PropertySource(name = "psName", value="classpath:org/springframework/context/annotation/missing.properties"),
|
||||
@PropertySource(name = "psName", value="classpath:org/springframework/context/annotation/p2.properties")
|
||||
@PropertySource(name = "psName", value = "classpath:org/springframework/context/annotation/p1.properties"),
|
||||
@PropertySource(name = "psName", value = "classpath:org/springframework/context/annotation/p2.properties"),
|
||||
})
|
||||
static class ConfigWithNamedPropertySources {
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@PropertySources({
|
||||
@PropertySource(name = "psName", value = "classpath:org/springframework/context/annotation/p1.properties"),
|
||||
@PropertySource(name = "psName", value = "classpath:org/springframework/context/annotation/missing.properties"),
|
||||
@PropertySource(name = "psName", value = "classpath:org/springframework/context/annotation/p2.properties")
|
||||
})
|
||||
static class ConfigWithMissingPropertySource {
|
||||
}
|
||||
@@ -288,10 +304,10 @@ public class PropertySourceAnnotationTests {
|
||||
|
||||
@Configuration
|
||||
@PropertySources({
|
||||
@PropertySource(name = "psName", value="classpath:org/springframework/context/annotation/p1.properties"),
|
||||
@PropertySource(name = "psName", value="classpath:org/springframework/context/annotation/missing.properties", ignoreResourceNotFound=true),
|
||||
@PropertySource(name = "psName", value="classpath:${myPath}/missing.properties", ignoreResourceNotFound=true),
|
||||
@PropertySource(name = "psName", value="classpath:org/springframework/context/annotation/p2.properties")
|
||||
@PropertySource(name = "psName", value = "classpath:org/springframework/context/annotation/p1.properties"),
|
||||
@PropertySource(name = "psName", value = "classpath:org/springframework/context/annotation/missing.properties", ignoreResourceNotFound=true),
|
||||
@PropertySource(name = "psName", value = "classpath:${myPath}/missing.properties", ignoreResourceNotFound=true),
|
||||
@PropertySource(name = "psName", value = "classpath:org/springframework/context/annotation/p2.properties")
|
||||
})
|
||||
static class ConfigWithIgnoredPropertySource {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user