Introduce ConfigurableEnvironment#merge
Prior to this change, AbstractApplicationContext#setParent replaced the child context's Environment with the parent's Environment if available. This has the negative effect of potentially changing the type of the child context's Environment, and in any case causes property sources added directly against the child environment to be ignored. This situation could easily occur if a WebApplicationContext child had a non-web ApplicationContext set as its parent. In this case the parent Environment type would (likely) be StandardEnvironment, while the child Environment type would (likely) be StandardServletEnvironment. By directly inheriting the parent environment, critical property sources such as ServletContextPropertySource are lost entirely. This commit introduces the concept of merging an environment through the new ConfigurableEnvironment#merge method. Instead of replacing the child's environment with the parent's, AbstractApplicationContext#setParent now merges property sources as well as active and default profile names from the parent into the child. In this way, distinct environment objects are maintained with specific types and property sources preserved. See #merge Javadoc for additional details. Issue: SPR-9444, SPR-9439
This commit is contained in:
@@ -56,6 +56,47 @@ public class StandardEnvironmentTests {
|
||||
|
||||
private ConfigurableEnvironment environment = new StandardEnvironment();
|
||||
|
||||
@Test
|
||||
public void merge() {
|
||||
ConfigurableEnvironment child = new StandardEnvironment();
|
||||
child.setActiveProfiles("c1", "c2");
|
||||
child.getPropertySources().addLast(
|
||||
new MockPropertySource("childMock")
|
||||
.withProperty("childKey", "childVal")
|
||||
.withProperty("bothKey", "childBothVal"));
|
||||
|
||||
ConfigurableEnvironment parent = new StandardEnvironment();
|
||||
parent.setActiveProfiles("p1", "p2");
|
||||
parent.getPropertySources().addLast(
|
||||
new MockPropertySource("parentMock")
|
||||
.withProperty("parentKey", "parentVal")
|
||||
.withProperty("bothKey", "parentBothVal"));
|
||||
|
||||
assertThat(child.getProperty("childKey"), is("childVal"));
|
||||
assertThat(child.getProperty("parentKey"), nullValue());
|
||||
assertThat(child.getProperty("bothKey"), is("childBothVal"));
|
||||
|
||||
assertThat(parent.getProperty("childKey"), nullValue());
|
||||
assertThat(parent.getProperty("parentKey"), is("parentVal"));
|
||||
assertThat(parent.getProperty("bothKey"), is("parentBothVal"));
|
||||
|
||||
assertThat(child.getActiveProfiles(), equalTo(new String[]{"c1","c2"}));
|
||||
assertThat(parent.getActiveProfiles(), equalTo(new String[]{"p1","p2"}));
|
||||
|
||||
child.merge(parent);
|
||||
|
||||
assertThat(child.getProperty("childKey"), is("childVal"));
|
||||
assertThat(child.getProperty("parentKey"), is("parentVal"));
|
||||
assertThat(child.getProperty("bothKey"), is("childBothVal"));
|
||||
|
||||
assertThat(parent.getProperty("childKey"), nullValue());
|
||||
assertThat(parent.getProperty("parentKey"), is("parentVal"));
|
||||
assertThat(parent.getProperty("bothKey"), is("parentBothVal"));
|
||||
|
||||
assertThat(child.getActiveProfiles(), equalTo(new String[]{"c1","c2","p1","p2"}));
|
||||
assertThat(parent.getActiveProfiles(), equalTo(new String[]{"p1","p2"}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertySourceOrder() {
|
||||
ConfigurableEnvironment env = new StandardEnvironment();
|
||||
|
||||
Reference in New Issue
Block a user