Browse Source

Register environment in all bean factories in a hierarchy

Prior to this change, AbstractApplicationContext#prepareBeanFactory
registered a bean named 'environment' once and only once within a given
ApplicationContext hierarchy. This worked fine with the expectation
that the Environment object is always delegated downward to children of
that hierarchy. However, with SPR-9444 and the introduction of
ConfigurableEnvironment#merge, this expectation was violated; each
member of an application context hierarchy now maintains its own
distinct Environment instance, which means that by extension that each
application context's underlying BeanFactory should have its own
'environment' bean pointing to that context's environment instance.

This problem could manifest in getting the wrong environment instance
when calling #getBean(Environment) or when @Autowiring an Environment
instance, for example into a @Configuration class. As reported in
SPR-9756, this could result in false negative property lookups or
incorrect results when checking whether a profile is active.

This commit ensures that every bean factory in an application
hierarchy has an 'environment' bean referring to the object returned
from the enclosing ApplicationContext#getEnvironment method.

Issue: SPR-9756, SPR-9444
pull/124/merge
Chris Beams 14 years ago
parent
commit
f963d0f190
  1. 4
      spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java
  2. 54
      spring-context/src/test/java/org/springframework/context/support/EnvironmentIntegrationTests.java

4
spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -566,7 +566,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader @@ -566,7 +566,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
// Register default environment beans.
if (!beanFactory.containsBean(ENVIRONMENT_BEAN_NAME)) {
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}

54
spring-context/src/test/java/org/springframework/context/support/EnvironmentIntegrationTests.java

@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.support;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
/**
* Tests covering the integration of {@link Environment} into {@link ApplicationContext}
* hierarchies.
*
* @author Chris Beams
*/
public class EnvironmentIntegrationTests {
@SuppressWarnings("unchecked")
@Test
public void repro() {
ConfigurableApplicationContext parent = new GenericApplicationContext();
parent.refresh();
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
child.setParent(parent);
child.refresh();
ConfigurableEnvironment env = child.getBean(ConfigurableEnvironment.class);
assertThat("unknown env", env, anyOf(
sameInstance(parent.getEnvironment()),
sameInstance(child.getEnvironment())));
assertThat("expected child ctx env", env, sameInstance(child.getEnvironment()));
}
}
Loading…
Cancel
Save