Skip to content

Commit 3cdb866

Browse files
committed
Relax ConfigurableWebEnvironment signatures
ConfigurableWebEnvironment was introduced in 3.2.0.M1 with SPR-9439 in order to break a cyclic dependency. At the same time, certain signatures such as AbstractRefreshableWebApplicationContext#getEnviroment and GenericWebApplicationContext#getEnvironment were updated to take advantage of covariant return types and return this newer, more narrow type and providing cast-free calls to ConfigurableWebEnvironment methods where necessary. Similar changes were made to HttpServletBean in 3.2.0.M2 with SPR-9763. Narrowing #getEnvironment signatures in this fashion required enforcing at the #setEnvironment level that any Environment instance provided (explicitly or via the EnvironmentAware callback) must be an instance of ConfigurableWebEnvironment. This is a reasonable assertion in typical web application scenarios, but as SPR-10138 demonstrates, there are valid use cases in which one may want or need to inject a non-web ConfigurableEnvironment variant, e.g. during automated unit/integration testing. On review, it was never strictly necessary to narrow #getEnvironment signatures, although doing so did provided convenience and type safety. In order to maintain as flexible and backward-compatible an arrangement as possible, this commit relaxes these #getEnvironment signatures back to their original, pre-3.2 state. Namely, they now return ConfigurableEnvironment as opposed to ConfigurableWebEnvironment, and in accordance, all instanceof assertions have been removed or relaxed to ensure that injected Environment instances are of type ConfigurableEnvironment. These changes have been verified against David Winterfeldt's Spring by Example spring-rest-services project, as described at SPR-10138. Issue: SPR-10138, SPR-9763, SPR-9439
1 parent d9a4fb4 commit 3cdb866

File tree

8 files changed

+36
-55
lines changed

8 files changed

+36
-55
lines changed

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 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,11 +71,6 @@ 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-
7974
/**
8075
* Set the namespace for this web application context,
8176
* to be used for building a default context config location.

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
3939
import org.springframework.core.GenericTypeResolver;
4040
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
41+
import org.springframework.core.env.ConfigurableEnvironment;
4142
import org.springframework.core.io.ClassPathResource;
4243
import org.springframework.core.io.support.PropertiesLoaderUtils;
4344
import org.springframework.util.Assert;
@@ -490,7 +491,10 @@ protected void customizeContext(ServletContext servletContext, ConfigurableWebAp
490491
initializerInstances.add(BeanUtils.instantiateClass(initializerClass));
491492
}
492493

493-
applicationContext.getEnvironment().initPropertySources(servletContext, null);
494+
ConfigurableEnvironment env = applicationContext.getEnvironment();
495+
if (env instanceof ConfigurableWebEnvironment) {
496+
((ConfigurableWebEnvironment)env).initPropertySources(servletContext, null);
497+
}
494498

495499
Collections.sort(initializerInstances, new AnnotationAwareOrderComparator());
496500
for (ApplicationContextInitializer<ConfigurableApplicationContext> initializer : initializerInstances) {

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

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 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,6 @@
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;
3130
import org.springframework.web.context.ConfigurableWebApplicationContext;
3231
import org.springframework.web.context.ConfigurableWebEnvironment;
3332
import org.springframework.web.context.ServletConfigAware;
@@ -157,15 +156,6 @@ protected ConfigurableEnvironment createEnvironment() {
157156
return new StandardServletEnvironment();
158157
}
159158

160-
@Override
161-
public ConfigurableWebEnvironment getEnvironment() {
162-
ConfigurableEnvironment env = super.getEnvironment();
163-
Assert.isInstanceOf(ConfigurableWebEnvironment.class, env,
164-
"ConfigurableWebApplicationContext environment must be of type " +
165-
"ConfigurableWebEnvironment");
166-
return (ConfigurableWebEnvironment) env;
167-
}
168-
169159
/**
170160
* Register request/session scopes, a {@link ServletContextAwareProcessor}, etc.
171161
*/
@@ -212,7 +202,11 @@ protected void onRefresh() {
212202
@Override
213203
protected void initPropertySources() {
214204
super.initPropertySources();
215-
this.getEnvironment().initPropertySources(this.servletContext, this.servletConfig);
205+
ConfigurableEnvironment env = this.getEnvironment();
206+
if (env instanceof ConfigurableWebEnvironment) {
207+
((ConfigurableWebEnvironment)env).initPropertySources(
208+
this.servletContext, this.servletConfig);
209+
}
216210
}
217211

218212
public Theme getTheme(String themeName) {

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

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 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.
@@ -147,15 +147,6 @@ protected ConfigurableEnvironment createEnvironment() {
147147
return new StandardServletEnvironment();
148148
}
149149

150-
@Override
151-
public ConfigurableWebEnvironment getEnvironment() {
152-
ConfigurableEnvironment env = super.getEnvironment();
153-
Assert.isInstanceOf(ConfigurableWebEnvironment.class, env,
154-
"ConfigurableWebApplicationContext environment must be of type " +
155-
"ConfigurableWebEnvironment");
156-
return (ConfigurableWebEnvironment) env;
157-
}
158-
159150
/**
160151
* Register ServletContextAwareProcessor.
161152
* @see ServletContextAwareProcessor
@@ -202,7 +193,11 @@ protected void onRefresh() {
202193
@Override
203194
protected void initPropertySources() {
204195
super.initPropertySources();
205-
this.getEnvironment().initPropertySources(this.servletContext, null);
196+
ConfigurableEnvironment env = this.getEnvironment();
197+
if (env instanceof ConfigurableWebEnvironment) {
198+
((ConfigurableWebEnvironment)env).initPropertySources(
199+
this.servletContext, null);
200+
}
206201
}
207202

208203
public Theme getTheme(String themeName) {

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

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 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,9 +27,7 @@
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;
3130
import org.springframework.web.context.ConfigurableWebApplicationContext;
32-
import org.springframework.web.context.ConfigurableWebEnvironment;
3331
import org.springframework.web.context.ServletConfigAware;
3432
import org.springframework.web.context.ServletContextAware;
3533

@@ -169,15 +167,6 @@ protected ConfigurableEnvironment createEnvironment() {
169167
return new StandardServletEnvironment();
170168
}
171169

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-
181170
/**
182171
* Initialize the theme capability.
183172
*/

spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 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.
@@ -39,11 +39,13 @@
3939
import org.springframework.context.i18n.LocaleContextHolder;
4040
import org.springframework.context.i18n.SimpleLocaleContext;
4141
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
42+
import org.springframework.core.env.ConfigurableEnvironment;
4243
import org.springframework.util.ClassUtils;
4344
import org.springframework.util.ObjectUtils;
4445
import org.springframework.util.StringUtils;
4546
import org.springframework.web.bind.annotation.RequestMethod;
4647
import org.springframework.web.context.ConfigurableWebApplicationContext;
48+
import org.springframework.web.context.ConfigurableWebEnvironment;
4749
import org.springframework.web.context.WebApplicationContext;
4850
import org.springframework.web.context.request.NativeWebRequest;
4951
import org.springframework.web.context.request.RequestAttributes;
@@ -638,7 +640,10 @@ protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicati
638640
// the context is refreshed; do it eagerly here to ensure servlet property sources
639641
// are in place for use in any post-processing or initialization that occurs
640642
// below prior to #refresh
641-
wac.getEnvironment().initPropertySources(getServletContext(), getServletConfig());
643+
ConfigurableEnvironment env = wac.getEnvironment();
644+
if (env instanceof ConfigurableWebEnvironment) {
645+
((ConfigurableWebEnvironment)env).initPropertySources(getServletContext(), getServletConfig());
646+
}
642647

643648
postProcessWebApplicationContext(wac);
644649

spring-webmvc/src/main/java/org/springframework/web/servlet/HttpServletBean.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 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,24 +27,23 @@
2727

2828
import org.apache.commons.logging.Log;
2929
import org.apache.commons.logging.LogFactory;
30-
3130
import org.springframework.beans.BeanWrapper;
3231
import org.springframework.beans.BeansException;
3332
import org.springframework.beans.MutablePropertyValues;
3433
import org.springframework.beans.PropertyAccessorFactory;
3534
import org.springframework.beans.PropertyValue;
3635
import org.springframework.beans.PropertyValues;
3736
import org.springframework.context.EnvironmentAware;
37+
import org.springframework.core.env.ConfigurableEnvironment;
3838
import org.springframework.core.env.Environment;
3939
import org.springframework.core.env.EnvironmentCapable;
4040
import org.springframework.core.io.Resource;
4141
import org.springframework.core.io.ResourceEditor;
4242
import org.springframework.core.io.ResourceLoader;
4343
import org.springframework.util.Assert;
4444
import org.springframework.util.StringUtils;
45-
import org.springframework.web.context.ConfigurableWebEnvironment;
46-
import org.springframework.web.context.support.StandardServletEnvironment;
4745
import org.springframework.web.context.support.ServletContextResourceLoader;
46+
import org.springframework.web.context.support.StandardServletEnvironment;
4847

4948
/**
5049
* Simple extension of {@link javax.servlet.http.HttpServlet} which treats
@@ -91,7 +90,7 @@ public abstract class HttpServletBean extends HttpServlet
9190
*/
9291
private final Set<String> requiredProperties = new HashSet<String>();
9392

94-
private ConfigurableWebEnvironment environment;
93+
private ConfigurableEnvironment environment;
9594

9695

9796
/**
@@ -187,19 +186,19 @@ protected void initServletBean() throws ServletException {
187186
/**
188187
* {@inheritDoc}
189188
* @throws IllegalArgumentException if environment is not assignable to
190-
* {@code ConfigurableWebEnvironment}.
189+
* {@code ConfigurableEnvironment}.
191190
*/
192191
public void setEnvironment(Environment environment) {
193-
Assert.isInstanceOf(ConfigurableWebEnvironment.class, environment);
194-
this.environment = (ConfigurableWebEnvironment)environment;
192+
Assert.isInstanceOf(ConfigurableEnvironment.class, environment);
193+
this.environment = (ConfigurableEnvironment) environment;
195194
}
196195

197196
/**
198197
* {@inheritDoc}
199198
* <p>If {@code null}, a new environment will be initialized via
200199
* {@link #createEnvironment()}.
201200
*/
202-
public ConfigurableWebEnvironment getEnvironment() {
201+
public ConfigurableEnvironment getEnvironment() {
203202
if (this.environment == null) {
204203
this.environment = this.createEnvironment();
205204
}
@@ -210,7 +209,7 @@ public ConfigurableWebEnvironment getEnvironment() {
210209
* Create and return a new {@link StandardServletEnvironment}. Subclasses may override
211210
* in order to configure the environment or specialize the environment type returned.
212211
*/
213-
protected ConfigurableWebEnvironment createEnvironment() {
212+
protected ConfigurableEnvironment createEnvironment() {
214213
return new StandardServletEnvironment();
215214
}
216215

spring-webmvc/src/test/java/org/springframework/web/servlet/DispatcherServletTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,7 @@ public void testDispatcherServletContextRefresh() throws ServletException {
833833

834834
public void testEnvironmentOperations() {
835835
DispatcherServlet servlet = new DispatcherServlet();
836-
ConfigurableWebEnvironment defaultEnv = servlet.getEnvironment();
836+
ConfigurableEnvironment defaultEnv = servlet.getEnvironment();
837837
assertThat(defaultEnv, notNullValue());
838838
ConfigurableEnvironment env1 = new StandardServletEnvironment();
839839
servlet.setEnvironment(env1); // should succeed

0 commit comments

Comments
 (0)