Add placeholder resolution to @PropertySource processing

Previously the core Spring processing of @PropertySource would
resolve placeholders in the location attribute, but the pre-loading
of the property source by Spring Boot didn't do that. Now implemented
using Environment.resolvePlaceholders() (N.B. at a time when the only
Environment entries available are system properties and OS env vars).

E.g.

	@Configuration
	@PropertySource("classpath:/${source.location}.properties")
	protected static class WithPropertySourcePlaceholders {
           ...
	}
pull/336/merge
Dave Syer 11 years ago
parent ca7201b4b2
commit 76c56c6aa9

@ -360,11 +360,9 @@ public class ConfigFileApplicationListener implements
candidates.add(LOCATION_VARIABLE); candidates.add(LOCATION_VARIABLE);
// @PropertySource annotation locations go last here (eventually highest // @PropertySource annotation locations go last here (eventually highest
// priority). This unfortunately isn't the same semantics as @PropertySource // priority). This unfortunately isn't the same semantics as @PropertySource
// in // in Spring and it's hard to change that (so the property source gets added
// Spring and it's hard to change that (so the property source gets added // again in last position by Spring later in the cycle).
// again in addLoadCandidatesFromAnnotations(environment, resourceLoader, candidates);
// last position by Spring later in the cycle).
addLoadCandidatesFromAnnotations(resourceLoader, candidates);
this.candidates = new ArrayList<String>(candidates); this.candidates = new ArrayList<String>(candidates);
Collections.reverse(this.candidates); Collections.reverse(this.candidates);
} }
@ -382,11 +380,13 @@ public class ConfigFileApplicationListener implements
} }
} }
private void addLoadCandidatesFromAnnotations(ResourceLoader resourceLoader, private void addLoadCandidatesFromAnnotations(
ConfigurableEnvironment environment, ResourceLoader resourceLoader,
Set<String> candidates) { Set<String> candidates) {
for (String location : ConfigFileApplicationListener.this.annotations for (String location : ConfigFileApplicationListener.this.annotations
.getLocations()) { .getLocations()) {
Resource resource = resourceLoader.getResource(location); Resource resource = resourceLoader.getResource(environment
.resolvePlaceholders(location));
if (!ConfigFileApplicationListener.this.annotations if (!ConfigFileApplicationListener.this.annotations
.ignoreResourceNotFound(location) && !resource.exists()) { .ignoreResourceNotFound(location) && !resource.exists()) {
throw new IllegalStateException("Resource not found: " + location); throw new IllegalStateException("Resource not found: " + location);

@ -272,6 +272,22 @@ public class ConfigFileApplicationListenerTests {
context.close(); context.close();
} }
@Test
public void propertySourceAnnotationWithPlaceholder() throws Exception {
EnvironmentTestUtils.addEnvironment(this.environment,
"source.location:specificlocation");
SpringApplication application = new SpringApplication(
WithPropertySourcePlaceholders.class);
application.setEnvironment(this.environment);
application.setWebEnvironment(false);
ConfigurableApplicationContext context = application.run();
String property = context.getEnvironment().getProperty("my.property");
assertThat(property, equalTo("fromspecificlocation"));
assertNotNull(context.getEnvironment().getPropertySources()
.get("classpath:/specificlocation.properties"));
context.close();
}
@Test @Test
public void propertySourceAnnotationWithName() throws Exception { public void propertySourceAnnotationWithName() throws Exception {
SpringApplication application = new SpringApplication( SpringApplication application = new SpringApplication(
@ -376,6 +392,12 @@ public class ConfigFileApplicationListenerTests {
} }
@Configuration
@PropertySource("classpath:/${source.location}.properties")
protected static class WithPropertySourcePlaceholders {
}
@Configuration @Configuration
@PropertySource(value = "classpath:/specificlocation.properties", name = "foo") @PropertySource(value = "classpath:/specificlocation.properties", name = "foo")
protected static class WithPropertySourceAndName { protected static class WithPropertySourceAndName {

Loading…
Cancel
Save