Polishing

This commit is contained in:
Juergen Hoeller 2014-01-15 23:46:52 +01:00
parent 5fb2665d1c
commit 68b1eb1aba
7 changed files with 55 additions and 84 deletions

View File

@ -61,11 +61,12 @@ import org.springframework.util.StringUtils;
*/ */
public abstract class AbstractContextLoader implements SmartContextLoader { public abstract class AbstractContextLoader implements SmartContextLoader {
private static final Log logger = LogFactory.getLog(AbstractContextLoader.class);
private static final String[] EMPTY_STRING_ARRAY = new String[0]; private static final String[] EMPTY_STRING_ARRAY = new String[0];
private static final String SLASH = "/"; private static final String SLASH = "/";
private static final Log logger = LogFactory.getLog(AbstractContextLoader.class);
// --- SmartContextLoader ----------------------------------------------- // --- SmartContextLoader -----------------------------------------------
@ -79,23 +80,19 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* processed locations are then * processed locations are then
* {@link ContextConfigurationAttributes#setLocations(String[]) set} in * {@link ContextConfigurationAttributes#setLocations(String[]) set} in
* the supplied configuration attributes. * the supplied configuration attributes.
*
* <p>Can be overridden in subclasses &mdash; for example, to process * <p>Can be overridden in subclasses &mdash; for example, to process
* annotated classes instead of resource locations. * annotated classes instead of resource locations.
*
* @since 3.1 * @since 3.1
* @see #processLocations(Class, String...) * @see #processLocations(Class, String...)
*/ */
public void processContextConfiguration(ContextConfigurationAttributes configAttributes) { public void processContextConfiguration(ContextConfigurationAttributes configAttributes) {
String[] processedLocations = processLocations(configAttributes.getDeclaringClass(), String[] processedLocations = processLocations(configAttributes.getDeclaringClass(), configAttributes.getLocations());
configAttributes.getLocations());
configAttributes.setLocations(processedLocations); configAttributes.setLocations(processedLocations);
} }
/** /**
* Prepare the {@link ConfigurableApplicationContext} created by this * Prepare the {@link ConfigurableApplicationContext} created by this
* {@code SmartContextLoader} <i>before</i> bean definitions are read. * {@code SmartContextLoader} <i>before</i> bean definitions are read.
*
* <p>The default implementation: * <p>The default implementation:
* <ul> * <ul>
* <li>Sets the <em>active bean definition profiles</em> from the supplied * <li>Sets the <em>active bean definition profiles</em> from the supplied
@ -106,17 +103,15 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* {@linkplain ApplicationContextInitializer#initialize invokes each} with the * {@linkplain ApplicationContextInitializer#initialize invokes each} with the
* given application context.</li> * given application context.</li>
* </ul> * </ul>
*
* <p>Any {@code ApplicationContextInitializers} implementing * <p>Any {@code ApplicationContextInitializers} implementing
* {@link org.springframework.core.Ordered Ordered} or marked with {@link * {@link org.springframework.core.Ordered Ordered} or marked with {@link
* org.springframework.core.annotation.Order @Order} will be sorted appropriately. * org.springframework.core.annotation.Order @Order} will be sorted appropriately.
*
* @param context the newly created application context * @param context the newly created application context
* @param mergedConfig the merged context configuration * @param mergedConfig the merged context configuration
* @since 3.2
* @see ApplicationContextInitializer#initialize(ConfigurableApplicationContext) * @see ApplicationContextInitializer#initialize(ConfigurableApplicationContext)
* @see #loadContext(MergedContextConfiguration) * @see #loadContext(MergedContextConfiguration)
* @see ConfigurableApplicationContext#setId * @see ConfigurableApplicationContext#setId
* @since 3.2
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected void prepareContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { protected void prepareContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
@ -129,17 +124,18 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
return; return;
} }
final List<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerInstances = new ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>>(); List<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerInstances =
final Class<?> contextClass = context.getClass(); new ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>>();
Class<?> contextClass = context.getClass();
for (Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>> initializerClass : initializerClasses) { for (Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>> initializerClass : initializerClasses) {
Class<?> initializerContextClass = GenericTypeResolver.resolveTypeArgument(initializerClass, Class<?> initializerContextClass = GenericTypeResolver.resolveTypeArgument(initializerClass,
ApplicationContextInitializer.class); ApplicationContextInitializer.class);
Assert.isAssignable(initializerContextClass, contextClass, String.format( Assert.isAssignable(initializerContextClass, contextClass, String.format(
"Could not add context initializer [%s] since its generic parameter [%s] " "Could not add context initializer [%s] since its generic parameter [%s] " +
+ "is not assignable from the type of application context used by this " "is not assignable from the type of application context used by this " +
+ "context loader [%s]: ", initializerClass.getName(), initializerContextClass.getName(), "context loader [%s]: ", initializerClass.getName(), initializerContextClass.getName(),
contextClass.getName())); contextClass.getName()));
initializerInstances.add((ApplicationContextInitializer<ConfigurableApplicationContext>) BeanUtils.instantiateClass(initializerClass)); initializerInstances.add((ApplicationContextInitializer<ConfigurableApplicationContext>) BeanUtils.instantiateClass(initializerClass));
} }
@ -160,7 +156,6 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* {@link #getResourceSuffix() resource suffix}; otherwise, the supplied * {@link #getResourceSuffix() resource suffix}; otherwise, the supplied
* {@code locations} will be {@link #modifyLocations modified} if * {@code locations} will be {@link #modifyLocations modified} if
* necessary and returned. * necessary and returned.
*
* @param clazz the class with which the locations are associated: to be * @param clazz the class with which the locations are associated: to be
* used when generating default locations * used when generating default locations
* @param locations the unmodified locations to use for loading the * @param locations the unmodified locations to use for loading the
@ -174,29 +169,25 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* @see #processContextConfiguration(ContextConfigurationAttributes) * @see #processContextConfiguration(ContextConfigurationAttributes)
*/ */
public final String[] processLocations(Class<?> clazz, String... locations) { public final String[] processLocations(Class<?> clazz, String... locations) {
return (ObjectUtils.isEmpty(locations) && isGenerateDefaultLocations()) ? generateDefaultLocations(clazz) return (ObjectUtils.isEmpty(locations) && isGenerateDefaultLocations()) ?
: modifyLocations(clazz, locations); generateDefaultLocations(clazz) : modifyLocations(clazz, locations);
} }
/** /**
* Generate the default classpath resource locations array based on the * Generate the default classpath resource locations array based on the
* supplied class. * supplied class.
*
* <p>For example, if the supplied class is {@code com.example.MyTest}, * <p>For example, if the supplied class is {@code com.example.MyTest},
* the generated locations will contain a single string with a value of * the generated locations will contain a single string with a value of
* &quot;classpath:/com/example/MyTest{@code <suffix>}&quot;, * &quot;classpath:/com/example/MyTest{@code <suffix>}&quot;,
* where {@code <suffix>} is the value of the * where {@code <suffix>} is the value of the
* {@link #getResourceSuffix() resource suffix} string. * {@link #getResourceSuffix() resource suffix} string.
*
* <p>As of Spring 3.1, the implementation of this method adheres to the * <p>As of Spring 3.1, the implementation of this method adheres to the
* contract defined in the {@link SmartContextLoader} SPI. Specifically, * contract defined in the {@link SmartContextLoader} SPI. Specifically,
* this method will <em>preemptively</em> verify that the generated default * this method will <em>preemptively</em> verify that the generated default
* location actually exists. If it does not exist, this method will log a * location actually exists. If it does not exist, this method will log a
* warning and return an empty array. * warning and return an empty array.
*
* <p>Subclasses can override this method to implement a different * <p>Subclasses can override this method to implement a different
* <em>default location generation</em> strategy. * <em>default location generation</em> strategy.
*
* @param clazz the class for which the default locations are to be generated * @param clazz the class for which the default locations are to be generated
* @return an array of default application context resource locations * @return an array of default application context resource locations
* @since 2.5 * @since 2.5
@ -212,23 +203,22 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
if (classPathResource.exists()) { if (classPathResource.exists()) {
if (logger.isInfoEnabled()) { if (logger.isInfoEnabled()) {
logger.info(String.format("Detected default resource location \"%s\" for test class [%s].", logger.info(String.format("Detected default resource location \"%s\" for test class [%s]",
prefixedResourcePath, clazz.getName())); prefixedResourcePath, clazz.getName()));
} }
return new String[] { prefixedResourcePath }; return new String[] {prefixedResourcePath};
} }
else {
// else if (logger.isInfoEnabled()) {
if (logger.isInfoEnabled()) { logger.info(String.format("Could not detect default resource locations for test class [%s]: " +
logger.info(String.format("Could not detect default resource locations for test class [%s]: " "%s does not exist", clazz.getName(), classPathResource));
+ "%s does not exist.", clazz.getName(), classPathResource)); }
return EMPTY_STRING_ARRAY;
} }
return EMPTY_STRING_ARRAY;
} }
/** /**
* Generate a modified version of the supplied locations array and return it. * Generate a modified version of the supplied locations array and return it.
*
* <p>A plain path &mdash; for example, &quot;context.xml&quot; &mdash; will * <p>A plain path &mdash; for example, &quot;context.xml&quot; &mdash; will
* be treated as a classpath resource that is relative to the package in which * be treated as a classpath resource that is relative to the package in which
* the specified class is defined. A path starting with a slash is treated * the specified class is defined. A path starting with a slash is treated
@ -238,10 +228,8 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* {@link ResourceUtils#CLASSPATH_URL_PREFIX classpath:}, * {@link ResourceUtils#CLASSPATH_URL_PREFIX classpath:},
* {@link ResourceUtils#FILE_URL_PREFIX file:}, {@code http:}, * {@link ResourceUtils#FILE_URL_PREFIX file:}, {@code http:},
* etc.) will be added to the results unchanged. * etc.) will be added to the results unchanged.
*
* <p>Subclasses can override this method to implement a different * <p>Subclasses can override this method to implement a different
* <em>location modification</em> strategy. * <em>location modification</em> strategy.
*
* @param clazz the class with which the locations are associated * @param clazz the class with which the locations are associated
* @param locations the resource locations to be modified * @param locations the resource locations to be modified
* @return an array of modified application context resource locations * @return an array of modified application context resource locations
@ -253,10 +241,12 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
String path = locations[i]; String path = locations[i];
if (path.startsWith(SLASH)) { if (path.startsWith(SLASH)) {
modifiedLocations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path; modifiedLocations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path;
} else if (!ResourcePatternUtils.isUrl(path)) { }
modifiedLocations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + SLASH else if (!ResourcePatternUtils.isUrl(path)) {
+ StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(clazz) + SLASH + path); modifiedLocations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + SLASH +
} else { StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(clazz) + SLASH + path);
}
else {
modifiedLocations[i] = StringUtils.cleanPath(path); modifiedLocations[i] = StringUtils.cleanPath(path);
} }
} }
@ -267,7 +257,6 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* Determine whether or not <em>default</em> resource locations should be * Determine whether or not <em>default</em> resource locations should be
* generated if the {@code locations} provided to * generated if the {@code locations} provided to
* {@link #processLocations(Class, String...)} are {@code null} or empty. * {@link #processLocations(Class, String...)} are {@code null} or empty.
*
* <p>As of Spring 3.1, the semantics of this method have been overloaded * <p>As of Spring 3.1, the semantics of this method have been overloaded
* to include detection of either default resource locations or default * to include detection of either default resource locations or default
* configuration classes. Consequently, this method can also be used to * configuration classes. Consequently, this method can also be used to
@ -276,9 +265,7 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* {@link ContextConfigurationAttributes configuration attributes} supplied * {@link ContextConfigurationAttributes configuration attributes} supplied
* to {@link #processContextConfiguration(ContextConfigurationAttributes)} * to {@link #processContextConfiguration(ContextConfigurationAttributes)}
* are {@code null} or empty. * are {@code null} or empty.
*
* <p>Can be overridden by subclasses to change the default behavior. * <p>Can be overridden by subclasses to change the default behavior.
*
* @return always {@code true} by default * @return always {@code true} by default
* @since 2.5 * @since 2.5
*/ */
@ -289,9 +276,7 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
/** /**
* Get the suffix to append to {@link ApplicationContext} resource locations * Get the suffix to append to {@link ApplicationContext} resource locations
* when generating default locations. * when generating default locations.
*
* <p>Must be implemented by subclasses. * <p>Must be implemented by subclasses.
*
* @return the resource suffix; should not be {@code null} or empty * @return the resource suffix; should not be {@code null} or empty
* @since 2.5 * @since 2.5
* @see #generateDefaultLocations(Class) * @see #generateDefaultLocations(Class)

View File

@ -201,11 +201,9 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
*/ */
@Override @Override
protected void initPropertySources() { protected void initPropertySources() {
super.initPropertySources(); ConfigurableEnvironment env = getEnvironment();
ConfigurableEnvironment env = this.getEnvironment();
if (env instanceof ConfigurableWebEnvironment) { if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment)env).initPropertySources( ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, this.servletConfig);
this.servletContext, this.servletConfig);
} }
} }

View File

@ -28,7 +28,6 @@ import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.ui.context.Theme; import org.springframework.ui.context.Theme;
import org.springframework.ui.context.ThemeSource; import org.springframework.ui.context.ThemeSource;
import org.springframework.ui.context.support.UiApplicationContextUtils; import org.springframework.ui.context.support.UiApplicationContextUtils;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.context.ConfigurableWebApplicationContext; import org.springframework.web.context.ConfigurableWebApplicationContext;
@ -192,11 +191,9 @@ public class GenericWebApplicationContext extends GenericApplicationContext
*/ */
@Override @Override
protected void initPropertySources() { protected void initPropertySources() {
super.initPropertySources(); ConfigurableEnvironment env = getEnvironment();
ConfigurableEnvironment env = this.getEnvironment();
if (env instanceof ConfigurableWebEnvironment) { if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment)env).initPropertySources( ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null);
this.servletContext, null);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -41,8 +41,7 @@ import org.springframework.web.context.ConfigurableWebEnvironment;
* @since 3.1 * @since 3.1
* @see StandardEnvironment * @see StandardEnvironment
*/ */
public class StandardServletEnvironment extends StandardEnvironment public class StandardServletEnvironment extends StandardEnvironment implements ConfigurableWebEnvironment {
implements ConfigurableWebEnvironment {
/** Servlet context init parameters property source name: {@value} */ /** Servlet context init parameters property source name: {@value} */
public static final String SERVLET_CONTEXT_PROPERTY_SOURCE_NAME = "servletContextInitParams"; public static final String SERVLET_CONTEXT_PROPERTY_SOURCE_NAME = "servletContextInitParams";
@ -91,8 +90,7 @@ public class StandardServletEnvironment extends StandardEnvironment
} }
public void initPropertySources(ServletContext servletContext, ServletConfig servletConfig) { public void initPropertySources(ServletContext servletContext, ServletConfig servletConfig) {
WebApplicationContextUtils.initServletPropertySources( WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig);
this.getPropertySources(), servletContext, servletConfig);
} }
} }

View File

@ -177,9 +177,8 @@ public class StaticWebApplicationContext extends StaticApplicationContext
@Override @Override
protected void initPropertySources() { protected void initPropertySources() {
super.initPropertySources(); WebApplicationContextUtils.initServletPropertySources(getEnvironment().getPropertySources(),
WebApplicationContextUtils.initServletPropertySources( this.servletContext, this.servletConfig);
this.getEnvironment().getPropertySources(), this.servletContext, this.servletConfig);
} }
public Theme getTheme(String themeName) { public Theme getTheme(String themeName) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,15 +16,11 @@
package org.springframework.web.context.support; package org.springframework.web.context.support;
import static org.springframework.web.context.support.StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME;
import static org.springframework.web.context.support.StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.faces.context.ExternalContext; import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import javax.servlet.ServletConfig; import javax.servlet.ServletConfig;
@ -51,11 +47,11 @@ import org.springframework.web.context.request.WebRequest;
/** /**
* Convenience methods for retrieving the root * Convenience methods for retrieving the root
* {@link org.springframework.web.context.WebApplicationContext} for a given * {@link org.springframework.web.context.WebApplicationContext} for a given
* {@code ServletContext}. This is e.g. useful for accessing a Spring * {@code ServletContext}. This is useful for programmatically accessing a
* context from within custom web views or Struts actions. * Spring application context from within custom web views or MVC actions.
* *
* <p>Note that there are more convenient ways of accessing the root context for * <p>Note that there are more convenient ways of accessing the root context for
* many web frameworks, either part of Spring or available as external library. * many web frameworks, either part of Spring or available as an external library.
* This helper class is just the most generic way to access the root context. * This helper class is just the most generic way to access the root context.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
@ -63,7 +59,6 @@ import org.springframework.web.context.request.WebRequest;
* @see org.springframework.web.servlet.FrameworkServlet * @see org.springframework.web.servlet.FrameworkServlet
* @see org.springframework.web.servlet.DispatcherServlet * @see org.springframework.web.servlet.DispatcherServlet
* @see org.springframework.web.jsf.FacesContextUtils * @see org.springframework.web.jsf.FacesContextUtils
* @see org.springframework.web.jsf.SpringBeanVariableResolver
* @see org.springframework.web.jsf.el.SpringBeanFacesELResolver * @see org.springframework.web.jsf.el.SpringBeanFacesELResolver
*/ */
public abstract class WebApplicationContextUtils { public abstract class WebApplicationContextUtils {
@ -260,16 +255,17 @@ public abstract class WebApplicationContextUtils {
*/ */
public static void initServletPropertySources( public static void initServletPropertySources(
MutablePropertySources propertySources, ServletContext servletContext, ServletConfig servletConfig) { MutablePropertySources propertySources, ServletContext servletContext, ServletConfig servletConfig) {
Assert.notNull(propertySources, "propertySources must not be null"); Assert.notNull(propertySources, "propertySources must not be null");
if(servletContext != null && if (servletContext != null && propertySources.contains(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME) &&
propertySources.contains(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME) && propertySources.get(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME) instanceof StubPropertySource) {
propertySources.get(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME) instanceof StubPropertySource) { propertySources.replace(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME,
propertySources.replace(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME, new ServletContextPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME, servletContext)); new ServletContextPropertySource(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME, servletContext));
} }
if(servletConfig != null && if (servletConfig != null && propertySources.contains(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME) &&
propertySources.contains(SERVLET_CONFIG_PROPERTY_SOURCE_NAME) && propertySources.get(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME) instanceof StubPropertySource) {
propertySources.get(SERVLET_CONFIG_PROPERTY_SOURCE_NAME) instanceof StubPropertySource) { propertySources.replace(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME,
propertySources.replace(SERVLET_CONFIG_PROPERTY_SOURCE_NAME, new ServletConfigPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME, servletConfig)); new ServletConfigPropertySource(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME, servletConfig));
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -78,10 +78,8 @@ public class StaticPortletApplicationContext extends StaticApplicationContext
*/ */
@Override @Override
protected void initPropertySources() { protected void initPropertySources() {
super.initPropertySources(); PortletApplicationContextUtils.initPortletPropertySources(getEnvironment().getPropertySources(),
PortletApplicationContextUtils.initPortletPropertySources( this.servletContext, this.portletContext, this.portletConfig);
this.getEnvironment().getPropertySources(), this.servletContext,
this.portletContext, this.portletConfig);
} }
/** /**