Polishing

This commit is contained in:
Juergen Hoeller
2014-08-12 22:24:50 +02:00
parent 3038f03fee
commit 0c89279d61
10 changed files with 100 additions and 85 deletions

View File

@@ -602,12 +602,15 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
if (this.logger.isInfoEnabled()) {
this.logger.info("Pre-instantiating singletons in " + this);
}
List<String> beanNames;
synchronized (this.beanDefinitionMap) {
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
beanNames = new ArrayList<String>(this.beanDefinitionNames);
}
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 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.
@@ -129,7 +129,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
public Object getBean(String name, Object... args) throws BeansException {
if (args != null) {
throw new UnsupportedOperationException(
"StaticListableBeanFactory does not support explicit bean creation arguments)");
"StaticListableBeanFactory does not support explicit bean creation arguments");
}
return getBean(name);
}

View File

@@ -130,7 +130,7 @@ public class SimpleJndiBeanFactory extends JndiLocatorSupport implements BeanFac
public Object getBean(String name, Object... args) throws BeansException {
if (args != null) {
throw new UnsupportedOperationException(
"SimpleJndiBeanFactory does not support explicit bean creation arguments)");
"SimpleJndiBeanFactory does not support explicit bean creation arguments");
}
return getBean(name);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 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.
@@ -167,8 +167,8 @@ public abstract class AbstractPropertyResolver implements ConfigurablePropertyRe
* @see #setIgnoreUnresolvableNestedPlaceholders
*/
protected String resolveNestedPlaceholders(String value) {
return this.ignoreUnresolvableNestedPlaceholders ?
resolvePlaceholders(value) : resolveRequiredPlaceholders(value);
return (this.ignoreUnresolvableNestedPlaceholders ?
resolvePlaceholders(value) : resolveRequiredPlaceholders(value));
}
private PropertyPlaceholderHelper createPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 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.
@@ -62,8 +62,8 @@ public class PropertyPlaceholderHelper {
/**
* Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix.
* Unresolvable placeholders are ignored.
* @param placeholderPrefix the prefix that denotes the start of a placeholder.
* @param placeholderSuffix the suffix that denotes the end of a placeholder.
* @param placeholderPrefix the prefix that denotes the start of a placeholder
* @param placeholderSuffix the suffix that denotes the end of a placeholder
*/
public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix) {
this(placeholderPrefix, placeholderSuffix, null, true);
@@ -75,14 +75,14 @@ public class PropertyPlaceholderHelper {
* @param placeholderSuffix the suffix that denotes the end of a placeholder
* @param valueSeparator the separating character between the placeholder variable
* and the associated default value, if any
* @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should be ignored
* ({@code true}) or cause an exception ({@code false}).
* @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should
* be ignored ({@code true}) or cause an exception ({@code false})
*/
public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix,
String valueSeparator, boolean ignoreUnresolvablePlaceholders) {
Assert.notNull(placeholderPrefix, "placeholderPrefix must not be null");
Assert.notNull(placeholderSuffix, "placeholderSuffix must not be null");
Assert.notNull(placeholderPrefix, "'placeholderPrefix' must not be null");
Assert.notNull(placeholderSuffix, "'placeholderSuffix' must not be null");
this.placeholderPrefix = placeholderPrefix;
this.placeholderSuffix = placeholderSuffix;
String simplePrefixForSuffix = wellKnownSimplePrefixes.get(this.placeholderSuffix);
@@ -100,12 +100,12 @@ public class PropertyPlaceholderHelper {
/**
* Replaces all placeholders of format {@code ${name}} with the corresponding
* property from the supplied {@link Properties}.
* @param value the value containing the placeholders to be replaced.
* @param properties the {@code Properties} to use for replacement.
* @return the supplied value with placeholders replaced inline.
* @param value the value containing the placeholders to be replaced
* @param properties the {@code Properties} to use for replacement
* @return the supplied value with placeholders replaced inline
*/
public String replacePlaceholders(String value, final Properties properties) {
Assert.notNull(properties, "Argument 'properties' must not be null.");
Assert.notNull(properties, "'properties' must not be null");
return replacePlaceholders(value, new PlaceholderResolver() {
public String resolvePlaceholder(String placeholderName) {
return properties.getProperty(placeholderName);
@@ -116,25 +116,25 @@ public class PropertyPlaceholderHelper {
/**
* Replaces all placeholders of format {@code ${name}} with the value returned
* from the supplied {@link PlaceholderResolver}.
* @param value the value containing the placeholders to be replaced.
* @param placeholderResolver the {@code PlaceholderResolver} to use for replacement.
* @return the supplied value with placeholders replaced inline.
* @param value the value containing the placeholders to be replaced
* @param placeholderResolver the {@code PlaceholderResolver} to use for replacement
* @return the supplied value with placeholders replaced inline
*/
public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {
Assert.notNull(value, "Argument 'value' must not be null.");
Assert.notNull(value, "'value' must not be null");
return parseStringValue(value, placeholderResolver, new HashSet<String>());
}
protected String parseStringValue(
String strVal, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) {
StringBuilder buf = new StringBuilder(strVal);
StringBuilder result = new StringBuilder(strVal);
int startIndex = strVal.indexOf(this.placeholderPrefix);
while (startIndex != -1) {
int endIndex = findPlaceholderEndIndex(buf, startIndex);
int endIndex = findPlaceholderEndIndex(result, startIndex);
if (endIndex != -1) {
String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex);
String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);
String originalPlaceholder = placeholder;
if (!visitedPlaceholders.add(originalPlaceholder)) {
throw new IllegalArgumentException(
@@ -159,15 +159,15 @@ public class PropertyPlaceholderHelper {
// Recursive invocation, parsing placeholders contained in the
// previously resolved placeholder value.
propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
if (logger.isTraceEnabled()) {
logger.trace("Resolved placeholder '" + placeholder + "'");
}
startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());
startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());
}
else if (this.ignoreUnresolvablePlaceholders) {
// Proceed with unprocessed value.
startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
}
else {
throw new IllegalArgumentException("Could not resolve placeholder '" +
@@ -180,7 +180,7 @@ public class PropertyPlaceholderHelper {
}
}
return buf.toString();
return result.toString();
}
private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {
@@ -210,14 +210,13 @@ public class PropertyPlaceholderHelper {
/**
* Strategy interface used to resolve replacement values for placeholders contained in Strings.
* @see PropertyPlaceholderHelper
*/
public static interface PlaceholderResolver {
/**
* Resolves the supplied placeholder name into the replacement value.
* Resolve the supplied placeholder name to the replacement value.
* @param placeholderName the name of the placeholder to resolve
* @return the replacement value or {@code null} if no replacement is to be made
* @return the replacement value, or {@code null} if no replacement is to be made
*/
String resolvePlaceholder(String placeholderName);
}

View File

@@ -204,6 +204,17 @@ public class StandardEnvironmentTests {
System.getProperties().remove(DEFAULT_PROFILES_PROPERTY_NAME);
}
@Test(expected=IllegalArgumentException.class)
public void defaultProfileWithCircularPlaceholder() {
System.setProperty(DEFAULT_PROFILES_PROPERTY_NAME, "${spring.profiles.default}");
try {
environment.getDefaultProfiles();
}
finally {
System.getProperties().remove(DEFAULT_PROFILES_PROPERTY_NAME);
}
}
@Test
public void getActiveProfiles_systemPropertiesEmpty() {
assertThat(environment.getActiveProfiles().length, is(0));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 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.
@@ -26,16 +26,19 @@ import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.util.WebUtils;
/**
* Convenient superclass for application objects running in a WebApplicationContext.
* Provides {@code getWebApplicationContext()}, {@code getServletContext()},
* and {@code getTempDir()} methods.
* Convenient superclass for application objects running in a {@link WebApplicationContext}.
* Provides {@code getWebApplicationContext()}, {@code getServletContext()}, and
* {@code getTempDir()} accessors.
*
* <p>Note: It is generally recommended to use individual callback interfaces for the actual
* callbacks needed. This broad base class is primarily intended for use within the framework,
* in case of {@link ServletContext} access etc typically being needed.
*
* @author Juergen Hoeller
* @since 28.08.2003
* @see SpringBeanAutowiringSupport
*/
public abstract class WebApplicationObjectSupport extends ApplicationObjectSupport
implements ServletContextAware {
public abstract class WebApplicationObjectSupport extends ApplicationObjectSupport implements ServletContextAware {
private ServletContext servletContext;

View File

@@ -26,25 +26,24 @@ import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
/**
* Simple implementation of ViewResolver that interprets a view name
* as bean name in the current application context, i.e. in the XML
* file of the executing DispatcherServlet.
* A simple implementation of {@link org.springframework.web.servlet.ViewResolver}
* that interprets a view name as a bean name in the current application context,
* i.e. typically in the XML file of the executing {@code DispatcherServlet}.
*
* <p>This resolver can be handy for small applications, keeping all
* definitions ranging from controllers to views in the same place.
* For normal applications, XmlViewResolver will be the better choice, as
* it separates the XML view bean definitions into a dedicated views file.
* View beans should virtually never have references to any other
* application beans - such a separation will make this clear.
* <p>This resolver can be handy for small applications, keeping all definitions
* ranging from controllers to views in the same place. For larger applications,
* {@link XmlViewResolver} will be the better choice, as it separates the XML
* view bean definitions into a dedicated views file.
*
* <p>This ViewResolver does not support internationalization.
* Conside ResourceBundleViewResolver if you need to apply different
* view resources per locale.
* <p>Note: Neither this {@code ViewResolver} nor {@link XmlViewResolver} supports
* internationalization. Consider {@link ResourceBundleViewResolver} if you need
* to apply different view resources per locale.
*
* <p>Note: This ViewResolver implements the Ordered interface to allow for
* flexible participation in ViewResolver chaining. For example, some special
* views could be defined via this ViewResolver (giving it 0 as "order" value),
* while all remaining views could be resolved by a UrlBasedViewResolver.
* <p>Note: This {@code ViewResolver} implements the {@link Ordered} interface
* in order to allow for flexible participation in {@code ViewResolver} chaining.
* For example, some special views could be defined via this {@code ViewResolver}
* (giving it 0 as "order" value), while all remaining views could be resolved by
* a {@link UrlBasedViewResolver}.
*
* @author Juergen Hoeller
* @since 18.06.2003
@@ -62,14 +61,14 @@ public class BeanNameViewResolver extends WebApplicationObjectSupport implements
}
public int getOrder() {
return order;
return this.order;
}
public View resolveViewName(String viewName, Locale locale) throws BeansException {
ApplicationContext context = getApplicationContext();
if (!context.containsBean(viewName)) {
// Allow for ViewResolver chaining.
// Allow for ViewResolver chaining...
return null;
}
return context.getBean(viewName, View.class);

View File

@@ -36,24 +36,22 @@ import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.servlet.View;
/**
* {@link org.springframework.web.servlet.ViewResolver} implementation
* that uses bean definitions in a {@link ResourceBundle}, specified by
* the bundle basename.
* A {@link org.springframework.web.servlet.ViewResolver} implementation that uses
* bean definitions in a {@link ResourceBundle}, specified by the bundle basename.
*
* <p>The bundle is typically defined in a properties file, located in
* the class path. The default bundle basename is "views".
* <p>The bundle is typically defined in a properties file, located in the classpath.
* The default bundle basename is "views".
*
* <p>This {@code ViewResolver} supports localized view definitions,
* using the default support of {@link java.util.PropertyResourceBundle}.
* For example, the basename "views" will be resolved as class path resources
* "views_de_AT.properties", "views_de.properties", "views.properties" -
* for a given Locale "de_AT".
* <p>This {@code ViewResolver} supports localized view definitions, using the
* default support of {@link java.util.PropertyResourceBundle}. For example, the
* basename "views" will be resolved as class path resources "views_de_AT.properties",
* "views_de.properties", "views.properties" - for a given Locale "de_AT".
*
* <p>Note: this {@code ViewResolver} implements the {@link Ordered}
* interface to allow for flexible participation in {@code ViewResolver}
* chaining. For example, some special views could be defined via this
* {@code ViewResolver} (giving it 0 as "order" value), while all
* remaining views could be resolved by a {@link UrlBasedViewResolver}.
* <p>Note: This {@code ViewResolver} implements the {@link Ordered} interface
* in order to allow for flexible participation in {@code ViewResolver} chaining.
* For example, some special views could be defined via this {@code ViewResolver}
* (giving it 0 as "order" value), while all remaining views could be resolved by
* a {@link UrlBasedViewResolver}.
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -109,7 +107,7 @@ public class ResourceBundleViewResolver extends AbstractCachingViewResolver
* @see java.util.ResourceBundle#getBundle(String)
*/
public void setBasename(String basename) {
setBasenames(new String[] {basename});
setBasenames(basename);
}
/**
@@ -172,7 +170,7 @@ public class ResourceBundleViewResolver extends AbstractCachingViewResolver
* <p>Allows for pre-initialization of common Locales, eagerly checking
* the view configuration for those Locales.
*/
public void setLocalesToInitialize(Locale[] localesToInitialize) {
public void setLocalesToInitialize(Locale... localesToInitialize) {
this.localesToInitialize = localesToInitialize;
}
@@ -196,7 +194,7 @@ public class ResourceBundleViewResolver extends AbstractCachingViewResolver
return factory.getBean(viewName, View.class);
}
catch (NoSuchBeanDefinitionException ex) {
// to allow for ViewResolver chaining
// Allow for ViewResolver chaining...
return null;
}
}

View File

@@ -32,18 +32,20 @@ import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.servlet.View;
/**
* Implementation of ViewResolver that uses bean definitions in an
* XML file, specified by resource location. The file will typically
* be located in the WEB-INF directory; default is "/WEB-INF/views.xml".
* A {@link org.springframework.web.servlet.ViewResolver} implementation that uses
* bean definitions in a dedicated XML file for view definitions, specified by
* resource location. The file will typically be located in the WEB-INF directory;
* the default is "/WEB-INF/views.xml".
*
* <p>This ViewResolver does not support internationalization.
* Consider ResourceBundleViewResolver if you need to apply
* different view resources per locale.
* <p>This {@code ViewResolver} does not support internationalization at the level
* of its definition resources. Consider {@link ResourceBundleViewResolver} if you
* need to apply different view resources per locale.
*
* <p>Note: This ViewResolver implements the Ordered interface to allow for
* flexible participation in ViewResolver chaining. For example, some special
* views could be defined via this ViewResolver (giving it 0 as "order" value),
* while all remaining views could be resolved by a UrlBasedViewResolver.
* <p>Note: This {@code ViewResolver} implements the {@link Ordered} interface
* in order to allow for flexible participation in {@code ViewResolver} chaining.
* For example, some special views could be defined via this {@code ViewResolver}
* (giving it 0 as "order" value), while all remaining views could be resolved by
* a {@link UrlBasedViewResolver}.
*
* @author Juergen Hoeller
* @since 18.06.2003
@@ -70,7 +72,7 @@ public class XmlViewResolver extends AbstractCachingViewResolver
}
public int getOrder() {
return order;
return this.order;
}
/**
@@ -109,7 +111,7 @@ public class XmlViewResolver extends AbstractCachingViewResolver
return factory.getBean(viewName, View.class);
}
catch (NoSuchBeanDefinitionException ex) {
// to allow for ViewResolver chaining
// Allow for ViewResolver chaining...
return null;
}
}