From d4c609f2f0a0df41b3f8c3e37485397cda864671 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Wed, 27 Jan 2021 17:06:00 -0800 Subject: [PATCH] Allow customer resolver and property sources Add factory methods to `AbstractEnvironment` that allow a custom `ConfigurablePropertyResolver` and `MutablePropertySources` instance to be used. See gh-26462 --- .../core/env/AbstractEnvironment.java | 42 +++++++++++++++++-- .../core/env/StandardEnvironment.java | 8 ++++ .../core/env/CustomEnvironmentTests.java | 41 ++++++++++++++++++ .../support/StandardServletEnvironment.java | 8 ++++ 4 files changed, 95 insertions(+), 4 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java index 6a75edcb1c..622c8aead9 100644 --- a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java +++ b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java @@ -107,10 +107,9 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { private final Set defaultProfiles = new LinkedHashSet<>(getReservedDefaultProfiles()); - private final MutablePropertySources propertySources = new MutablePropertySources(); + private final MutablePropertySources propertySources; - private final ConfigurablePropertyResolver propertyResolver = - new PropertySourcesPropertyResolver(this.propertySources); + private final ConfigurablePropertyResolver propertyResolver; /** @@ -121,9 +120,44 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { * @see #customizePropertySources(MutablePropertySources) */ public AbstractEnvironment() { - customizePropertySources(this.propertySources); + this(new MutablePropertySources()); } + /** + * Create a new {@code Environment} instance with a specific + * {@link MutablePropertySources} instance, calling back to + * {@link #customizePropertySources(MutablePropertySources)} during + * construction to allow subclasses to contribute or manipulate + * {@link PropertySource} instances as appropriate. + * @see #customizePropertySources(MutablePropertySources) + * @since 5.3.4 + */ + protected AbstractEnvironment(MutablePropertySources propertySources) { + this.propertySources = propertySources; + this.propertyResolver = createPropertyResolver(propertySources); + customizePropertySources(propertySources); + } + + + /** + * Factory method used to create the {@link ConfigurablePropertyResolver} + * instance used by the Environment. + * @see #getPropertyResolver() + * @since 5.3.4 + */ + protected ConfigurablePropertyResolver createPropertyResolver( + MutablePropertySources propertySources) { + return new PropertySourcesPropertyResolver(propertySources); + } + + /** + * Return the {@link ConfigurablePropertyResolver} being used by the + * {@link Environment}. + * @see #createPropertyResolver(MutablePropertySources) + */ + protected final ConfigurablePropertyResolver getPropertyResolver() { + return this.propertyResolver; + } /** * Customize the set of {@link PropertySource} objects to be searched by this diff --git a/spring-core/src/main/java/org/springframework/core/env/StandardEnvironment.java b/spring-core/src/main/java/org/springframework/core/env/StandardEnvironment.java index fc4570684d..a3b46456b8 100644 --- a/spring-core/src/main/java/org/springframework/core/env/StandardEnvironment.java +++ b/spring-core/src/main/java/org/springframework/core/env/StandardEnvironment.java @@ -60,6 +60,14 @@ public class StandardEnvironment extends AbstractEnvironment { public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties"; + public StandardEnvironment() { + } + + protected StandardEnvironment(MutablePropertySources propertySources) { + super(propertySources); + } + + /** * Customize the set of property sources with those appropriate for any standard * Java environment: diff --git a/spring-core/src/test/java/org/springframework/core/env/CustomEnvironmentTests.java b/spring-core/src/test/java/org/springframework/core/env/CustomEnvironmentTests.java index dd7bac24ee..2aa5ef7ef3 100644 --- a/spring-core/src/test/java/org/springframework/core/env/CustomEnvironmentTests.java +++ b/spring-core/src/test/java/org/springframework/core/env/CustomEnvironmentTests.java @@ -129,6 +129,47 @@ class CustomEnvironmentTests { assertThat(env.getDefaultProfiles()).containsExactly(AbstractEnvironment.RESERVED_DEFAULT_PROFILE_NAME); } + @Test + public void withCustomMutablePropertySources() { + class CustomMutablePropertySources extends MutablePropertySources { + } + MutablePropertySources propertySources = new CustomMutablePropertySources(); + ConfigurableEnvironment env = new AbstractEnvironment(propertySources) { + }; + assertThat(env.getPropertySources()).isInstanceOf(CustomMutablePropertySources.class); + } + + @Test + void withCustomPropertyResolver() { + class CustomPropertySourcesPropertyResolver extends PropertySourcesPropertyResolver { + + public CustomPropertySourcesPropertyResolver( + PropertySources propertySources) { + super(propertySources); + } + + @Override + public String getProperty(String key) { + return super.getProperty(key)+"-test"; + } + + } + ConfigurableEnvironment env = new AbstractEnvironment() { + + @Override + protected ConfigurablePropertyResolver createPropertyResolver( + MutablePropertySources propertySources) { + return new CustomPropertySourcesPropertyResolver(propertySources); + } + + }; + Map values = new LinkedHashMap<>(); + values.put("spring", "framework"); + PropertySource propertySource = new MapPropertySource("test", values); + env.getPropertySources().addFirst(propertySource); + assertThat(env.getProperty("spring")).isEqualTo("framework-test"); + } + private Profiles defaultProfile() { return Profiles.of(AbstractEnvironment.RESERVED_DEFAULT_PROFILE_NAME); } diff --git a/spring-web/src/main/java/org/springframework/web/context/support/StandardServletEnvironment.java b/spring-web/src/main/java/org/springframework/web/context/support/StandardServletEnvironment.java index c3177c711e..9bc6fd7dc5 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/StandardServletEnvironment.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/StandardServletEnvironment.java @@ -54,6 +54,14 @@ public class StandardServletEnvironment extends StandardEnvironment implements C public static final String JNDI_PROPERTY_SOURCE_NAME = "jndiProperties"; + public StandardServletEnvironment() { + } + + protected StandardServletEnvironment(MutablePropertySources propertySources) { + super(propertySources); + } + + /** * Customize the set of property sources with those contributed by superclasses as * well as those appropriate for standard servlet-based environments: