From 7c72e3342ef79b00ce557c9b5d7e89297b5f4aeb Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 6 Jun 2014 09:40:56 +0100 Subject: [PATCH] Make late Environment changes appear in ConfigurationProperties --- ...urationPropertiesBindingPostProcessor.java | 115 ++++++++++-------- 1 file changed, 63 insertions(+), 52 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java b/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java index b4aae0c4af..96e76d6e15 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java @@ -17,6 +17,7 @@ package org.springframework.boot.context.properties; import java.io.IOException; +import java.util.Iterator; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanCreationException; @@ -205,15 +206,18 @@ public class ConfigurationPropertiesBindingPostProcessor implements BeanPostProc try { PropertySourcesPlaceholderConfigurer configurer = this.beanFactory .getBean(PropertySourcesPlaceholderConfigurer.class); - return extractPropertySources(configurer); + PropertySources propertySources = configurer.getAppliedPropertySources(); + // Flatten the sources into a single list so they can be iterated + return new FlatPropertySources(propertySources); } catch (NoSuchBeanDefinitionException ex) { // Continue if no PropertySourcesPlaceholderConfigurer bean } if (this.environment instanceof ConfigurableEnvironment) { - return flattenPropertySources(((ConfigurableEnvironment) this.environment) - .getPropertySources()); + MutablePropertySources propertySources = ((ConfigurableEnvironment) this.environment) + .getPropertySources(); + return new FlatPropertySources(propertySources); } // empty, so not very useful, but fulfils the contract @@ -229,55 +233,6 @@ public class ConfigurationPropertiesBindingPostProcessor implements BeanPostProc } } - /** - * Convenience method to extract PropertySources from an existing (and already - * initialized) PropertySourcesPlaceholderConfigurer. As long as this method is - * executed late enough in the context lifecycle it will come back with data. We can - * rely on the fact that PropertySourcesPlaceholderConfigurer is a - * BeanFactoryPostProcessor and is therefore initialized early. - * @param configurer a PropertySourcesPlaceholderConfigurer - * @return some PropertySources - */ - private PropertySources extractPropertySources( - PropertySourcesPlaceholderConfigurer configurer) { - PropertySources propertySources = configurer.getAppliedPropertySources(); - // Flatten the sources into a single list so they can be iterated - return flattenPropertySources(propertySources); - } - - /** - * Flatten out a tree of property sources. - * @param propertySources some PropertySources, possibly containing environment - * properties - * @return another PropertySources containing the same properties - */ - private PropertySources flattenPropertySources(PropertySources propertySources) { - MutablePropertySources result = new MutablePropertySources(); - for (PropertySource propertySource : propertySources) { - flattenPropertySources(propertySource, result); - } - return result; - } - - /** - * Convenience method to allow recursive flattening of property sources. - * @param propertySource a property source to flatten - * @param result the cumulative result - */ - private void flattenPropertySources(PropertySource propertySource, - MutablePropertySources result) { - Object source = propertySource.getSource(); - if (source instanceof ConfigurableEnvironment) { - ConfigurableEnvironment environment = (ConfigurableEnvironment) source; - for (PropertySource childSource : environment.getPropertySources()) { - flattenPropertySources(childSource, result); - } - } - else { - result.addLast(propertySource); - } - } - @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { @@ -425,4 +380,60 @@ public class ConfigurationPropertiesBindingPostProcessor implements BeanPostProc } + /** + * Convenience class to flatten out a tree of property sources without losing the + * reference to the backing data (which can therefore be updated in the background). + * + * @param propertySources some PropertySources, possibly containing environment + * properties + * @return another PropertySources containing the same properties + */ + private static class FlatPropertySources implements PropertySources { + + private PropertySources propertySources; + + public FlatPropertySources(PropertySources propertySources) { + this.propertySources = propertySources; + } + + @Override + public Iterator> iterator() { + MutablePropertySources result = getFlattened(); + return result.iterator(); + } + + @Override + public boolean contains(String name) { + return get(name) != null; + } + + @Override + public PropertySource get(String name) { + return getFlattened().get(name); + } + + private MutablePropertySources getFlattened() { + MutablePropertySources result = new MutablePropertySources(); + for (PropertySource propertySource : propertySources) { + flattenPropertySources(propertySource, result); + } + return result; + } + + private void flattenPropertySources(PropertySource propertySource, + MutablePropertySources result) { + Object source = propertySource.getSource(); + if (source instanceof ConfigurableEnvironment) { + ConfigurableEnvironment environment = (ConfigurableEnvironment) source; + for (PropertySource childSource : environment.getPropertySources()) { + flattenPropertySources(childSource, result); + } + } + else { + result.addLast(propertySource); + } + } + + } + }