Resolve ${...} placeholders in @PropertySource
Issue: SPR-8442 git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4516 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
419288562b
commit
cf8533fb97
|
|
@ -177,6 +177,7 @@ class ConfigurationClassParser {
|
|||
String[] locations = (String[]) propertySourceAttributes.get("value");
|
||||
ClassLoader classLoader = this.resourceLoader.getClassLoader();
|
||||
for (String location : locations) {
|
||||
location = this.environment.resolveRequiredPlaceholders(location);
|
||||
ResourcePropertySource ps = StringUtils.hasText(name) ?
|
||||
new ResourcePropertySource(name, location, classLoader) :
|
||||
new ResourcePropertySource(location, classLoader);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,32 @@ import java.lang.annotation.Target;
|
|||
* configuration class and then used when populating the {@code TestBean} object. Given
|
||||
* the configuration above, a call to {@code testBean.getName()} will return "myTestBean".
|
||||
*
|
||||
* <h3>Resolving placeholders within @PropertySource resource locations</h3>
|
||||
* Any ${...} placeholders present in a {@code @PropertySource} {@linkplain #value()
|
||||
* resource location} will be resolved against the set of property sources already
|
||||
* registered against the environment. For example:
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties")
|
||||
* public class AppConfig {
|
||||
* @Autowired
|
||||
* Environment env;
|
||||
*
|
||||
* @Bean
|
||||
* public TestBean testBean() {
|
||||
* TestBean testBean = new TestBean();
|
||||
* testBean.setName(env.getProperty("testbean.name"));
|
||||
* return testBean;
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* Assuming that "my.placeholder" is present in one of the property sources already
|
||||
* registered, e.g. system properties or environment variables, the placeholder will
|
||||
* be resolved to the corresponding value. If not, then "default/path" will be used as a
|
||||
* default. Expressing a default value (delimited by colon ":") is optional. If no
|
||||
* default is specified and a property cannot be resolved, an {@code
|
||||
* IllegalArgumentException} will be thrown.
|
||||
*
|
||||
* <h3>A note on property overriding with @PropertySource</h3>
|
||||
* In cases where a given property key exists in more than one {@code .properties}
|
||||
* file, the last {@code @PropertySource} annotation processed will 'win' and override.
|
||||
|
|
@ -119,11 +145,14 @@ public @interface PropertySource {
|
|||
/**
|
||||
* Indicate the resource location(s) of the properties file to be loaded.
|
||||
* For example, {@code "classpath:/com/myco/app.properties"} or
|
||||
* {@code "file:/path/to/file"}. Note that resource location wildcards
|
||||
* are not permitted, and that each location must evaluate to exactly one
|
||||
* {@code .properties} resource. Each location will be added to the
|
||||
* enclosing {@code Environment} as its own property source, and in the order
|
||||
* declared.
|
||||
* {@code "file:/path/to/file"}.
|
||||
* <p>Resource location wildcards (e.g. **/*.properties) are not permitted; each
|
||||
* location must evaluate to exactly one {@code .properties} resource.
|
||||
* <p>${...} placeholders will be resolved against any/all property sources already
|
||||
* registered with the {@code Environment}. See {@linkplain PropertySource above} for
|
||||
* examples.
|
||||
* <p>Each location will be added to the enclosing {@code Environment} as its own
|
||||
* property source, and in the order declared.
|
||||
*/
|
||||
String[] value();
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,62 @@ public class PropertySourceAnnotationTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void withUnresolvablePlaceholder() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ConfigWithUnresolvablePlaceholder.class);
|
||||
ctx.refresh();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withUnresolvablePlaceholderAndDefault() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ConfigWithUnresolvablePlaceholderAndDefault.class);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.getBean(TestBean.class).getName(), equalTo("p1TestBean"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withResolvablePlaceholder() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ConfigWithResolvablePlaceholder.class);
|
||||
System.setProperty("path.to.properties", "org/springframework/context/annotation");
|
||||
ctx.refresh();
|
||||
assertThat(ctx.getBean(TestBean.class).getName(), equalTo("p1TestBean"));
|
||||
System.clearProperty("path.to.properties");
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@PropertySource(value="classpath:${unresolvable}/p1.properties")
|
||||
static class ConfigWithUnresolvablePlaceholder {
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@PropertySource(value="classpath:${unresolvable:org/springframework/context/annotation}/p1.properties")
|
||||
static class ConfigWithUnresolvablePlaceholderAndDefault {
|
||||
@Inject Environment env;
|
||||
|
||||
@Bean
|
||||
public TestBean testBean() {
|
||||
return new TestBean(env.getProperty("testbean.name"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@PropertySource(value="classpath:${path.to.properties}/p1.properties")
|
||||
static class ConfigWithResolvablePlaceholder {
|
||||
@Inject Environment env;
|
||||
|
||||
@Bean
|
||||
public TestBean testBean() {
|
||||
return new TestBean(env.getProperty("testbean.name"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Configuration
|
||||
@PropertySource(name="p1", value="classpath:org/springframework/context/annotation/p1.properties")
|
||||
|
|
|
|||
Loading…
Reference in New Issue