Refactor to lazy Environment creation where possible

This commit avoids eager creation of Environment instances, favoring
delegation of already existing Environment objects where possible. For
example, FrameworkServlet creates an ApplicationContext; both require
a StandardServletEnvironment instance, and prior to this change, two
instances were created where one would suffice - indeed these two
instances may reasonably be expected to be the same. Now, the
FrameworkServlet defers creation of its Environment, allowing users to
supply a custom instance via its #setEnvironment method (e.g. within a
WebApplicationInitializer); the FrameworkServlet then takes care to
delegate that instance to the ApplicationContext created
in #createWebApplicationContext.

This behavior produces more consistent behavior with regard to
delegation of the environment, saves unnecessary cycles by avoiding
needless instantiation and calls to methods like
StandardServletEnvironment#initPropertySources and leads to better
logging output, as the user sees only one Environment created and
initialized when working with the FrameworkServlet/DispatcherServlet.

This commit also mirrors these changes across the corresponding
Portlet* classes.

Issue: SPR-9763
This commit is contained in:
Chris Beams
2012-09-05 21:55:41 +02:00
parent 9f8d219146
commit 6517517ca9
8 changed files with 117 additions and 23 deletions

View File

@@ -73,6 +73,7 @@ import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
@@ -224,7 +225,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
public AbstractApplicationContext(ApplicationContext parent) {
this.parent = parent;
this.resourcePatternResolver = getResourcePatternResolver();
this.environment = this.createEnvironment();
}
@@ -276,7 +276,15 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
return this.parent;
}
/**
* {@inheritDoc}
* <p>If {@code null}, a new environment will be initialized via
* {@link #createEnvironment()}.
*/
public ConfigurableEnvironment getEnvironment() {
if (this.environment == null) {
this.environment = this.createEnvironment();
}
return this.environment;
}
@@ -387,9 +395,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
public void setParent(ApplicationContext parent) {
this.parent = parent;
if (parent != null) {
Object parentEnvironment = parent.getEnvironment();
Environment parentEnvironment = parent.getEnvironment();
if (parentEnvironment instanceof ConfigurableEnvironment) {
this.environment.merge((ConfigurableEnvironment)parentEnvironment);
this.getEnvironment().merge((ConfigurableEnvironment)parentEnvironment);
}
}
}
@@ -505,7 +513,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
this.environment.validateRequiredProperties();
this.getEnvironment().validateRequiredProperties();
}
/**