Use PropertiesConfigurationFactory to bind to SpringApplication

Then non-enumerable property sources will be accessible (like
SystemProperties in principle). This is the same way that other
beans are bound to the environment, but this one never got the
same treatment.

Fixes gh-951, gh-934
This commit is contained in:
Dave Syer 2014-05-26 10:40:24 +01:00
parent 43481725b9
commit b3022fd24a
2 changed files with 24 additions and 4 deletions

View File

@ -31,8 +31,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.bind.PropertySourcesPropertyValues;
import org.springframework.boot.bind.RelaxedDataBinder;
import org.springframework.boot.bind.PropertiesConfigurationFactory;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.boot.env.EnumerableCompositePropertySource;
@ -54,6 +53,7 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindException;
/**
* {@link ApplicationListener} that configures the context environment by loading
@ -171,9 +171,17 @@ public class ConfigFileApplicationListener implements
*/
protected void bindToSpringApplication(ConfigurableEnvironment environment,
SpringApplication application) {
RelaxedDataBinder binder = new RelaxedDataBinder(application, "spring.main");
PropertiesConfigurationFactory<SpringApplication> binder = new PropertiesConfigurationFactory<SpringApplication>(
application);
binder.setTargetName("spring.main");
binder.setConversionService(this.conversionService);
binder.bind(new PropertySourcesPropertyValues(environment.getPropertySources()));
binder.setPropertySources(environment.getPropertySources());
try {
binder.bindPropertiesToTarget();
}
catch (BindException e) {
throw new IllegalStateException("Cannot bind to SpringApplication", e);
}
}
/**

View File

@ -82,6 +82,7 @@ public class ConfigFileApplicationListenerTests {
public void cleanup() {
System.clearProperty("my.property");
System.clearProperty("spring.config.location");
System.clearProperty("spring.main.showBanner");
}
@Test
@ -561,6 +562,17 @@ public class ConfigFileApplicationListenerTests {
assertThat((Boolean) field.get(application), equalTo(false));
}
@Test
public void bindsSystemPropertyToSpringApplication() throws Exception {
// gh-951
System.setProperty("spring.main.showBanner", "false");
this.initializer.onApplicationEvent(this.event);
SpringApplication application = this.event.getSpringApplication();
Field field = ReflectionUtils.findField(SpringApplication.class, "showBanner");
field.setAccessible(true);
assertThat((Boolean) field.get(application), equalTo(false));
}
private static Matcher<? super ConfigurableEnvironment> containsPropertySource(
final String sourceName) {
return new TypeSafeDiagnosingMatcher<ConfigurableEnvironment>() {