Commit 76c56c6a authored by Dave Syer's avatar Dave Syer

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 {
           ...
	}
parent ca7201b4
...@@ -360,11 +360,9 @@ public class ConfigFileApplicationListener implements ...@@ -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 ...@@ -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 { ...@@ -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 { ...@@ -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 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment