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

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 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.
@@ -345,6 +345,7 @@ public abstract class FrameworkPortlet extends GenericPortletBean
pac.setId(ConfigurablePortletApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + getPortletName());
}
pac.setEnvironment(this.getEnvironment());
pac.setParent(parent);
pac.setPortletContext(getPortletContext());
pac.setPortletConfig(getPortletConfig());

View File

@@ -34,13 +34,16 @@ import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.PropertyValues;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.portlet.context.StandardPortletEnvironment;
import org.springframework.web.portlet.context.PortletContextResourceLoader;
import org.springframework.web.portlet.context.StandardPortletEnvironment;
/**
* Simple extension of <code>javax.portlet.GenericPortlet</code> that treats
@@ -65,7 +68,8 @@ import org.springframework.web.portlet.context.PortletContextResourceLoader;
* @see #processAction
* @see FrameworkPortlet
*/
public abstract class GenericPortletBean extends GenericPortlet implements EnvironmentAware {
public abstract class GenericPortletBean extends GenericPortlet
implements EnvironmentCapable, EnvironmentAware {
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
@@ -76,7 +80,7 @@ public abstract class GenericPortletBean extends GenericPortlet implements Envir
*/
private final Set<String> requiredProperties = new HashSet<String>();
private Environment environment = new StandardPortletEnvironment();
private ConfigurableEnvironment environment;
/**
@@ -107,7 +111,7 @@ public abstract class GenericPortletBean extends GenericPortlet implements Envir
PropertyValues pvs = new PortletConfigPropertyValues(getPortletConfig(), this.requiredProperties);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new PortletContextResourceLoader(getPortletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment));
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.getEnvironment()));
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
}
@@ -167,17 +171,39 @@ public abstract class GenericPortletBean extends GenericPortlet implements Envir
/**
* {@inheritDoc}
* <p>Any environment set here overrides the {@link StandardPortletEnvironment}
* provided by default.
* @throws IllegalArgumentException if environment is not assignable to
* {@code ConfigurableEnvironment}.
*/
public void setEnvironment(Environment environment) {
this.environment = environment;
Assert.isInstanceOf(ConfigurableEnvironment.class, environment);
this.environment = (ConfigurableEnvironment)environment;
}
/**
* {@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;
}
/**
* Create and return a new {@link StandardPortletEnvironment}. Subclasses may override
* in order to configure the environment or specialize the environment type returned.
*/
protected ConfigurableEnvironment createEnvironment() {
return new StandardPortletEnvironment();
}
/**
* PropertyValues implementation created from PortletConfig init parameters.
*/
@SuppressWarnings("serial")
private static class PortletConfigPropertyValues extends MutablePropertyValues {
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 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.
@@ -75,7 +75,6 @@ public class StandardPortletEnvironment extends StandardEnvironment {
* @see org.springframework.core.env.AbstractEnvironment#customizePropertySources
* @see PortletConfigPropertySource
* @see PortletContextPropertySource
* @see AbstractRefreshablePortletApplicationContext#initPropertySources
* @see PortletApplicationContextUtils#initPortletPropertySources
*/
@Override