Allow ACI classes access to servlet context params
Prior to this commit, StandardServletEnvironment's servlet context PropertySource remained stubbed out until it the ServletContext became available and could be replaced during the refresh() of its enclosing WebApplicationContext. This behavior is acceptable in most cases. However, if the user has declared an ApplicationContextInitializer that attempts to access servlet context-params via the Environment API, this result in a kind of 'false negative', i.e. the context-param key and value are actually present in the ServletContext, but the PropertySource representing servlet context params is still a stub at this point, meaning that it returns an empty result in all cases. With this change, WebApplicationContextUtils#initServletPropertySources is invoked eagerly by the ContextLoader if any ACI classes have been declared. This swaps out the servlet context property source stub for the real thing just in time for ACIs to use it if necessary. Extra guard logic has been added to #initServletPropertySources to ensure idempotency -- once the stub has been replaced, the method never attempts the replacement again, e.g. during the normal context refresh() when this method will be called again. Issue: SPR-8991
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.springframework.web.context;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -131,6 +132,19 @@ public final class ContextLoaderTests {
|
||||
assertThat(wac.getServletContext().getAttribute("initialized"), notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisteredContextInitializerCanAccessServletContextParamsViaEnvironment() {
|
||||
MockServletContext sc = new MockServletContext("");
|
||||
// config file doesn't matter. just a placeholder
|
||||
sc.addInitParameter(ContextLoader.CONFIG_LOCATION_PARAM,
|
||||
"/org/springframework/web/context/WEB-INF/empty-context.xml");
|
||||
|
||||
sc.addInitParameter("someProperty", "someValue");
|
||||
sc.addInitParameter(ContextLoader.CONTEXT_INITIALIZER_CLASSES_PARAM, EnvApplicationContextInitializer.class.getName());
|
||||
ContextLoaderListener listener = new ContextLoaderListener();
|
||||
listener.contextInitialized(new ServletContextEvent(sc));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContextLoaderListenerWithUnkownContextInitializer() {
|
||||
MockServletContext sc = new MockServletContext("");
|
||||
@@ -324,6 +338,15 @@ public final class ContextLoaderTests {
|
||||
}
|
||||
}
|
||||
|
||||
private static class EnvApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableWebApplicationContext> {
|
||||
public void initialize(ConfigurableWebApplicationContext applicationContext) {
|
||||
// test that ApplicationContextInitializers can access ServletContext properties
|
||||
// via the environment (SPR-8991)
|
||||
String value = applicationContext.getEnvironment().getRequiredProperty("someProperty");
|
||||
assertThat(value, is("someValue"));
|
||||
}
|
||||
}
|
||||
|
||||
private static interface UnknownApplicationContext extends ConfigurableApplicationContext {
|
||||
void unheardOf();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user