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:
@@ -378,14 +378,19 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>The parent {@linkplain #getEnvironment() environment} is
|
||||
* delegated to this (child) context if the parent is a
|
||||
* {@link ConfigurableApplicationContext} implementation.
|
||||
* <p>The parent {@linkplain ApplicationContext#getEnvironment() environment} is
|
||||
* {@linkplain ConfigurableEnvironment#merge(ConfigurableEnvironment) merged} with
|
||||
* this (child) application context environment if the parent is non-{@code null} and
|
||||
* its environment is an instance of {@link ConfigurableEnvironment}.
|
||||
* @see ConfigurableEnvironment#merge(ConfigurableEnvironment)
|
||||
*/
|
||||
public void setParent(ApplicationContext parent) {
|
||||
this.parent = parent;
|
||||
if (parent instanceof ConfigurableApplicationContext) {
|
||||
this.setEnvironment(((ConfigurableApplicationContext)parent).getEnvironment());
|
||||
if (parent != null) {
|
||||
Object parentEnvironment = parent.getEnvironment();
|
||||
if (parentEnvironment instanceof ConfigurableEnvironment) {
|
||||
this.environment.merge((ConfigurableEnvironment)parentEnvironment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user