Merge branch '2.4.x'

Closes gh-25495
This commit is contained in:
Madhura Bhave 2021-03-04 09:46:26 -08:00
commit 9fd6a1e56a
4 changed files with 87 additions and 1 deletions

View File

@ -16,6 +16,7 @@
package org.springframework.boot;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
@ -72,6 +73,40 @@ public class DefaultPropertiesPropertySource extends MapPropertySource {
}
}
/**
* Add a new {@link DefaultPropertiesPropertySource} or merge with an existing one.
* @param source the {@code Map} source
* @param sources the existing sources
* @since 2.4.4
*/
public static void addOrMerge(Map<String, Object> source, MutablePropertySources sources) {
if (!CollectionUtils.isEmpty(source)) {
Map<String, Object> resultingSource = new HashMap<>();
DefaultPropertiesPropertySource propertySource = new DefaultPropertiesPropertySource(resultingSource);
if (sources.contains(NAME)) {
mergeIfPossible(source, sources, resultingSource);
sources.replace(NAME, propertySource);
}
else {
resultingSource.putAll(source);
sources.addLast(propertySource);
}
}
}
@SuppressWarnings("unchecked")
private static void mergeIfPossible(Map<String, Object> source, MutablePropertySources sources,
Map<String, Object> resultingSource) {
PropertySource<?> existingSource = sources.get(NAME);
if (existingSource != null) {
Object underlyingSource = existingSource.getSource();
if (underlyingSource instanceof Map) {
resultingSource.putAll((Map<String, Object>) underlyingSource);
}
resultingSource.putAll(source);
}
}
/**
* Move the 'defaultProperties' property source so that it's the last source in the
* given {@link ConfigurableEnvironment}.

View File

@ -518,7 +518,9 @@ public class SpringApplication {
*/
protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
MutablePropertySources sources = environment.getPropertySources();
DefaultPropertiesPropertySource.ifNotEmpty(this.defaultProperties, sources::addLast);
if (!CollectionUtils.isEmpty(this.defaultProperties)) {
DefaultPropertiesPropertySource.addOrMerge(this.defaultProperties, sources);
}
if (this.addCommandLineProperties && args.length > 0) {
String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME;
if (sources.contains(name)) {

View File

@ -26,6 +26,7 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.mock.env.MockEnvironment;
@ -39,6 +40,7 @@ import static org.mockito.Mockito.verifyNoInteractions;
* Tests for {@link DefaultPropertiesPropertySource}.
*
* @author Phillip Webb
* @author Madhura Bhave
*/
@ExtendWith(MockitoExtension.class)
class DefaultPropertiesPropertySourceTests {
@ -104,6 +106,39 @@ class DefaultPropertiesPropertySourceTests {
DefaultPropertiesPropertySource.moveToEnd(environment);
}
@Test
void addOrMergeWhenExistingNotFoundShouldAdd() {
MockEnvironment environment = new MockEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
DefaultPropertiesPropertySource.addOrMerge(Collections.singletonMap("spring", "boot"), propertySources);
assertThat(propertySources.contains(DefaultPropertiesPropertySource.NAME)).isTrue();
assertThat(propertySources.get(DefaultPropertiesPropertySource.NAME).getProperty("spring")).isEqualTo("boot");
}
@Test
void addOrMergeWhenExistingFoundShouldMerge() {
MockEnvironment environment = new MockEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
propertySources.addLast(new DefaultPropertiesPropertySource(Collections.singletonMap("spring", "boot")));
DefaultPropertiesPropertySource.addOrMerge(Collections.singletonMap("hello", "world"), propertySources);
assertThat(propertySources.contains(DefaultPropertiesPropertySource.NAME)).isTrue();
assertThat(propertySources.get(DefaultPropertiesPropertySource.NAME).getProperty("spring")).isEqualTo("boot");
assertThat(propertySources.get(DefaultPropertiesPropertySource.NAME).getProperty("hello")).isEqualTo("world");
}
@Test
void addOrMergeWhenExistingNotMapPropertySourceShouldNotMerge() {
MockEnvironment environment = new MockEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
CompositePropertySource composite = new CompositePropertySource(DefaultPropertiesPropertySource.NAME);
composite.addPropertySource(new DefaultPropertiesPropertySource(Collections.singletonMap("spring", "boot")));
propertySources.addFirst(composite);
DefaultPropertiesPropertySource.addOrMerge(Collections.singletonMap("hello", "world"), propertySources);
assertThat(propertySources.contains(DefaultPropertiesPropertySource.NAME)).isTrue();
assertThat(propertySources.get(DefaultPropertiesPropertySource.NAME).getProperty("spring")).isNull();
assertThat(propertySources.get(DefaultPropertiesPropertySource.NAME).getProperty("hello")).isEqualTo("world");
}
@Test
void moveToEndWhenPresentMovesToEnd() {
MockEnvironment environment = new MockEnvironment();

View File

@ -53,6 +53,7 @@ import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.AvailabilityState;
import org.springframework.boot.availability.LivenessState;
import org.springframework.boot.availability.ReadinessState;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.event.ApplicationContextInitializedEvent;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.context.event.ApplicationFailedEvent;
@ -105,6 +106,7 @@ import org.springframework.core.io.ResourceLoader;
import org.springframework.core.metrics.ApplicationStartup;
import org.springframework.core.metrics.StartupStep;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.test.context.support.TestPropertySourceUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@ -887,6 +889,18 @@ class SpringApplicationTests {
assertThat(getEnvironment().getProperty("baz")).isEqualTo("");
}
@Test
void defaultPropertiesShouldBeMerged() {
MockEnvironment environment = new MockEnvironment();
environment.getPropertySources().addFirst(
new MapPropertySource(DefaultPropertiesPropertySource.NAME, Collections.singletonMap("bar", "foo")));
SpringApplication application = new SpringApplicationBuilder(ExampleConfig.class).environment(environment)
.properties("baz=bing").web(WebApplicationType.NONE).build();
this.context = application.run();
assertThat(getEnvironment().getProperty("bar")).isEqualTo("foo");
assertThat(getEnvironment().getProperty("baz")).isEqualTo("bing");
}
@Test
void commandLineArgsApplyToSpringApplication() {
TestSpringApplication application = new TestSpringApplication(ExampleConfig.class);