Skip to content
This repository was archived by the owner on Oct 11, 2024. It is now read-only.

Commit 2a2b6ee

Browse files
committed
Introduce ConfigurableWebEnvironment
Changes introduced in Spring 3.1 for Environment support inadvertently established a cyclic dependency between the org.springframework.web.context and org.springframework.web.context.support packages, specifically through web.context.ContextLoader's invocation of web.context.support.WebApplicationContextUtils#initServletPropertySources. This commit introduces ConfigurableWebEnvironment to break this cyclic dependency. All web.context.ConfigurableWebApplicationContext types now return web.context.ConfigurableWebEnvironment from their #getEnvironment methods; web.context.support.StandardServletEnvironment now implements ConfigurableWebEnvironment and makes the call to web.context.support.WebApplicationContextUtils#initServletPropertySources within its implementation of #initPropertySources. This means that web.context.ContextLoader now invokes web.context.ConfigurableWebEnvironment#initPropertySources instead of web.context.support.WebApplicationContextUtils#initServletPropertySources and thus the cycle is broken. Issue: SPR-9439
1 parent 9fcfd7e commit 2a2b6ee

File tree

9 files changed

+120
-36
lines changed

9 files changed

+120
-36
lines changed

spring-web/src/main/java/org/springframework/web/context/ConfigurableWebApplicationContext.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -71,6 +71,11 @@ public interface ConfigurableWebApplicationContext extends WebApplicationContext
7171
*/
7272
ServletConfig getServletConfig();
7373

74+
/**
75+
* Return the {@link ConfigurableWebEnvironment} used by this web application context.
76+
*/
77+
ConfigurableWebEnvironment getEnvironment();
78+
7479
/**
7580
* Set the namespace for this web application context,
7681
* to be used for building a default context config location.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2002-2012 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.web.context;
18+
19+
import javax.servlet.ServletConfig;
20+
import javax.servlet.ServletContext;
21+
22+
import org.springframework.core.env.ConfigurableEnvironment;
23+
24+
/**
25+
* Specialization of {@link ConfigurableEnvironment} allowing initialization of
26+
* servlet-related {@link org.springframework.core.env.PropertySource} objects at the
27+
* earliest moment the {@link ServletContext} and (optionally) {@link ServletConfig}
28+
* become available.
29+
*
30+
* @author Chris Beams
31+
* @since 3.1.2
32+
* @see ConfigurableWebApplicationContext#getEnvironment()
33+
*/
34+
public interface ConfigurableWebEnvironment extends ConfigurableEnvironment {
35+
36+
/**
37+
* Replace any {@linkplain
38+
* org.springframework.core.env.PropertySource.StubPropertySource stub property source}
39+
* instances acting as placeholders with real servlet context/config property sources
40+
* using the given parameters.
41+
* @param servletContext the {@link ServletContext} (may not be {@code null})
42+
* @param servletConfig the {@link ServletContext} ({@code null} if not available)
43+
*/
44+
void initPropertySources(ServletContext servletContext, ServletConfig servletConfig);
45+
46+
}

spring-web/src/main/java/org/springframework/web/context/ContextLoader.java

+2-9
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import org.springframework.util.ClassUtils;
4545
import org.springframework.util.ObjectUtils;
4646
import org.springframework.util.StringUtils;
47-
import org.springframework.web.context.support.WebApplicationContextUtils;
4847

4948
/**
5049
* Performs the actual initialization work for the root application context.
@@ -485,15 +484,9 @@ protected void customizeContext(ServletContext servletContext, ConfigurableWebAp
485484
initializerInstances.add(BeanUtils.instantiateClass(initializerClass));
486485
}
487486

488-
Collections.sort(initializerInstances, new AnnotationAwareOrderComparator());
489-
490-
// eagerly attempt to initialize servlet property sources in case initializers
491-
// below depend on accessing context-params via the Environment API. Note that
492-
// depending on application context implementation, this initialization will be
493-
// attempted again during context refresh.
494-
WebApplicationContextUtils.initServletPropertySources(
495-
applicationContext.getEnvironment().getPropertySources(), servletContext);
487+
applicationContext.getEnvironment().initPropertySources(servletContext, null);
496488

489+
Collections.sort(initializerInstances, new AnnotationAwareOrderComparator());
497490
for (ApplicationContextInitializer<ConfigurableApplicationContext> initializer : initializerInstances) {
498491
initializer.initialize(applicationContext);
499492
}

spring-web/src/main/java/org/springframework/web/context/support/AbstractRefreshableWebApplicationContext.java

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,7 +27,9 @@
2727
import org.springframework.ui.context.Theme;
2828
import org.springframework.ui.context.ThemeSource;
2929
import org.springframework.ui.context.support.UiApplicationContextUtils;
30+
import org.springframework.util.Assert;
3031
import org.springframework.web.context.ConfigurableWebApplicationContext;
32+
import org.springframework.web.context.ConfigurableWebEnvironment;
3133
import org.springframework.web.context.ServletConfigAware;
3234
import org.springframework.web.context.ServletContextAware;
3335

@@ -139,6 +141,14 @@ protected ConfigurableEnvironment createEnvironment() {
139141
return new StandardServletEnvironment();
140142
}
141143

144+
@Override
145+
public ConfigurableWebEnvironment getEnvironment() {
146+
ConfigurableEnvironment env = super.getEnvironment();
147+
Assert.isInstanceOf(ConfigurableWebEnvironment.class, env,
148+
"ConfigurableWebApplicationContext environment must be of type " +
149+
"ConfigurableWebEnvironment");
150+
return (ConfigurableWebEnvironment) env;
151+
}
142152

143153
/**
144154
* Register request/session scopes, a {@link ServletContextAwareProcessor}, etc.
@@ -186,9 +196,7 @@ protected void onRefresh() {
186196
@Override
187197
protected void initPropertySources() {
188198
super.initPropertySources();
189-
WebApplicationContextUtils.initServletPropertySources(
190-
this.getEnvironment().getPropertySources(), this.servletContext,
191-
this.servletConfig);
199+
this.getEnvironment().initPropertySources(this.servletContext, this.servletConfig);
192200
}
193201

194202
public Theme getTheme(String themeName) {

spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,9 +28,11 @@
2828
import org.springframework.ui.context.Theme;
2929
import org.springframework.ui.context.ThemeSource;
3030
import org.springframework.ui.context.support.UiApplicationContextUtils;
31+
import org.springframework.util.Assert;
3132
import org.springframework.util.ObjectUtils;
3233
import org.springframework.util.StringUtils;
3334
import org.springframework.web.context.ConfigurableWebApplicationContext;
35+
import org.springframework.web.context.ConfigurableWebEnvironment;
3436
import org.springframework.web.context.ServletContextAware;
3537

3638
/**
@@ -130,6 +132,15 @@ protected ConfigurableEnvironment createEnvironment() {
130132
return new StandardServletEnvironment();
131133
}
132134

135+
@Override
136+
public ConfigurableWebEnvironment getEnvironment() {
137+
ConfigurableEnvironment env = super.getEnvironment();
138+
Assert.isInstanceOf(ConfigurableWebEnvironment.class, env,
139+
"ConfigurableWebApplicationContext environment must be of type " +
140+
"ConfigurableWebEnvironment");
141+
return (ConfigurableWebEnvironment) env;
142+
}
143+
133144
/**
134145
* Register ServletContextAwareProcessor.
135146
* @see ServletContextAwareProcessor
@@ -176,8 +187,7 @@ protected void onRefresh() {
176187
@Override
177188
protected void initPropertySources() {
178189
super.initPropertySources();
179-
WebApplicationContextUtils.initServletPropertySources(
180-
this.getEnvironment().getPropertySources(), this.servletContext);
190+
this.getEnvironment().initPropertySources(this.servletContext, null);
181191
}
182192

183193
public Theme getTheme(String themeName) {

spring-web/src/main/java/org/springframework/web/context/support/StandardServletEnvironment.java

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
2626
import org.springframework.core.env.StandardEnvironment;
2727
import org.springframework.jndi.JndiLocatorDelegate;
2828
import org.springframework.jndi.JndiPropertySource;
29+
import org.springframework.web.context.ConfigurableWebEnvironment;
2930

3031
/**
3132
* {@link Environment} implementation to be used by {@code Servlet}-based web
@@ -40,7 +41,8 @@
4041
* @since 3.1
4142
* @see StandardEnvironment
4243
*/
43-
public class StandardServletEnvironment extends StandardEnvironment {
44+
public class StandardServletEnvironment extends StandardEnvironment
45+
implements ConfigurableWebEnvironment {
4446

4547
/** Servlet context init parameters property source name: {@value} */
4648
public static final String SERVLET_CONTEXT_PROPERTY_SOURCE_NAME = "servletContextInitParams";
@@ -68,15 +70,15 @@ public class StandardServletEnvironment extends StandardEnvironment {
6870
* environment variables contributed by the {@link StandardEnvironment} superclass.
6971
* <p>The {@code Servlet}-related property sources are added as {@link
7072
* StubPropertySource stubs} at this stage, and will be {@linkplain
71-
* WebApplicationContextUtils#initServletPropertySources fully initialized} once the
72-
* actual {@link ServletConfig} and {@link ServletContext} objects become available.
73+
* #initPropertySources(ServletContext) fully initialized} once the actual
74+
* {@link ServletContext} object becomes available.
7375
* @see StandardEnvironment#customizePropertySources
7476
* @see org.springframework.core.env.AbstractEnvironment#customizePropertySources
7577
* @see ServletConfigPropertySource
7678
* @see ServletContextPropertySource
7779
* @see org.springframework.jndi.JndiPropertySource
7880
* @see org.springframework.context.support.AbstractApplicationContext#initPropertySources
79-
* @see WebApplicationContextUtils#initServletPropertySources
81+
* @see #initPropertySources(ServletContext)
8082
*/
8183
@Override
8284
protected void customizePropertySources(MutablePropertySources propertySources) {
@@ -88,4 +90,9 @@ protected void customizePropertySources(MutablePropertySources propertySources)
8890
super.customizePropertySources(propertySources);
8991
}
9092

93+
public void initPropertySources(ServletContext servletContext, ServletConfig servletConfig) {
94+
WebApplicationContextUtils.initServletPropertySources(
95+
this.getPropertySources(), servletContext, servletConfig);
96+
}
97+
9198
}

spring-web/src/main/java/org/springframework/web/context/support/StaticWebApplicationContext.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,7 +27,9 @@
2727
import org.springframework.ui.context.Theme;
2828
import org.springframework.ui.context.ThemeSource;
2929
import org.springframework.ui.context.support.UiApplicationContextUtils;
30+
import org.springframework.util.Assert;
3031
import org.springframework.web.context.ConfigurableWebApplicationContext;
32+
import org.springframework.web.context.ConfigurableWebEnvironment;
3133
import org.springframework.web.context.ServletConfigAware;
3234
import org.springframework.web.context.ServletContextAware;
3335

@@ -167,6 +169,15 @@ protected ConfigurableEnvironment createEnvironment() {
167169
return new StandardServletEnvironment();
168170
}
169171

172+
@Override
173+
public ConfigurableWebEnvironment getEnvironment() {
174+
ConfigurableEnvironment env = super.getEnvironment();
175+
Assert.isInstanceOf(ConfigurableWebEnvironment.class, env,
176+
"ConfigurableWebApplication environment must be of type " +
177+
"ConfigurableWebEnvironment");
178+
return (ConfigurableWebEnvironment) env;
179+
}
180+
170181
/**
171182
* Initialize the theme capability.
172183
*/

spring-webmvc/src/test/java/org/springframework/web/context/XmlWebApplicationContextTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2005 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

src/test/java/org/springframework/core/env/EnvironmentIntegrationTests.java

+16-12
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ public class EnvironmentIntegrationTests {
9999

100100
private ConfigurableEnvironment prodEnv;
101101
private ConfigurableEnvironment devEnv;
102+
private ConfigurableEnvironment prodWebEnv;
102103

103104
/**
104105
* Constants used both locally and in scan* sub-packages
@@ -125,6 +126,9 @@ public void setUp() {
125126

126127
devEnv = new StandardEnvironment();
127128
devEnv.setActiveProfiles(DEV_ENV_NAME);
129+
130+
prodWebEnv = new StandardServletEnvironment();
131+
prodWebEnv.setActiveProfiles(PROD_ENV_NAME);
128132
}
129133

130134
@Test
@@ -348,24 +352,24 @@ public void webApplicationContext() {
348352

349353
assertHasStandardServletEnvironment(ctx);
350354

351-
ctx.setEnvironment(prodEnv);
355+
ctx.setEnvironment(prodWebEnv);
352356
ctx.refresh();
353357

354-
assertHasEnvironment(ctx, prodEnv);
358+
assertHasEnvironment(ctx, prodWebEnv);
355359
assertEnvironmentBeanRegistered(ctx);
356-
assertEnvironmentAwareInvoked(ctx, prodEnv);
360+
assertEnvironmentAwareInvoked(ctx, prodWebEnv);
357361
}
358362

359363
@Test
360364
public void xmlWebApplicationContext() {
361365
AbstractRefreshableWebApplicationContext ctx = new XmlWebApplicationContext();
362366
ctx.setConfigLocation("classpath:" + XML_PATH);
363-
ctx.setEnvironment(prodEnv);
367+
ctx.setEnvironment(prodWebEnv);
364368
ctx.refresh();
365369

366-
assertHasEnvironment(ctx, prodEnv);
370+
assertHasEnvironment(ctx, prodWebEnv);
367371
assertEnvironmentBeanRegistered(ctx);
368-
assertEnvironmentAwareInvoked(ctx, prodEnv);
372+
assertEnvironmentAwareInvoked(ctx, prodWebEnv);
369373
assertThat(ctx.containsBean(DEV_BEAN_NAME), is(false));
370374
assertThat(ctx.containsBean(PROD_BEAN_NAME), is(true));
371375
}
@@ -394,24 +398,24 @@ public void staticWebApplicationContext() {
394398

395399
registerEnvironmentBeanDefinition(ctx);
396400

397-
ctx.setEnvironment(prodEnv);
401+
ctx.setEnvironment(prodWebEnv);
398402
ctx.refresh();
399403

400-
assertHasEnvironment(ctx, prodEnv);
404+
assertHasEnvironment(ctx, prodWebEnv);
401405
assertEnvironmentBeanRegistered(ctx);
402-
assertEnvironmentAwareInvoked(ctx, prodEnv);
406+
assertEnvironmentAwareInvoked(ctx, prodWebEnv);
403407
}
404408

405409
@Test
406410
public void annotationConfigWebApplicationContext() {
407411
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
408-
ctx.setEnvironment(prodEnv);
412+
ctx.setEnvironment(prodWebEnv);
409413
ctx.setConfigLocation(EnvironmentAwareBean.class.getName());
410414
ctx.refresh();
411415

412-
assertHasEnvironment(ctx, prodEnv);
416+
assertHasEnvironment(ctx, prodWebEnv);
413417
assertEnvironmentBeanRegistered(ctx);
414-
assertEnvironmentAwareInvoked(ctx, prodEnv);
418+
assertEnvironmentAwareInvoked(ctx, prodWebEnv);
415419
}
416420

417421
@Test

0 commit comments

Comments
 (0)