From 0c89279d61619df1f52b32251a7954eafd0984b9 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 12 Aug 2014 22:24:50 +0200 Subject: [PATCH] Polishing --- .../support/DefaultListableBeanFactory.java | 3 ++ .../support/StaticListableBeanFactory.java | 4 +- .../jndi/support/SimpleJndiBeanFactory.java | 2 +- .../core/env/AbstractPropertyResolver.java | 6 +-- .../util/PropertyPlaceholderHelper.java | 49 +++++++++---------- .../core/env/StandardEnvironmentTests.java | 11 +++++ .../support/WebApplicationObjectSupport.java | 15 +++--- .../servlet/view/BeanNameViewResolver.java | 35 +++++++------ .../view/ResourceBundleViewResolver.java | 34 ++++++------- .../web/servlet/view/XmlViewResolver.java | 26 +++++----- 10 files changed, 100 insertions(+), 85 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 7a874cce93..97a3788089 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -602,12 +602,15 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto if (this.logger.isInfoEnabled()) { this.logger.info("Pre-instantiating singletons in " + this); } + List 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(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()) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java index 8ad2e7bb49..16681cc4f3 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java @@ -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); } diff --git a/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java b/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java index 7772d9730f..558e271dee 100644 --- a/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java +++ b/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java @@ -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); } diff --git a/spring-core/src/main/java/org/springframework/core/env/AbstractPropertyResolver.java b/spring-core/src/main/java/org/springframework/core/env/AbstractPropertyResolver.java index 71aa9f46b2..f9e3d1f552 100644 --- a/spring-core/src/main/java/org/springframework/core/env/AbstractPropertyResolver.java +++ b/spring-core/src/main/java/org/springframework/core/env/AbstractPropertyResolver.java @@ -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) { diff --git a/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java b/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java index fca0f997f8..1ce878f852 100644 --- a/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java +++ b/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java @@ -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()); } protected String parseStringValue( String strVal, PlaceholderResolver placeholderResolver, Set 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); } diff --git a/spring-core/src/test/java/org/springframework/core/env/StandardEnvironmentTests.java b/spring-core/src/test/java/org/springframework/core/env/StandardEnvironmentTests.java index 01daf449dc..e094e342d2 100644 --- a/spring-core/src/test/java/org/springframework/core/env/StandardEnvironmentTests.java +++ b/spring-core/src/test/java/org/springframework/core/env/StandardEnvironmentTests.java @@ -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)); diff --git a/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationObjectSupport.java b/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationObjectSupport.java index 9aa2547d62..a5c7383bcf 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationObjectSupport.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationObjectSupport.java @@ -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. + * + *

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; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/BeanNameViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/BeanNameViewResolver.java index a8ca84e664..330fa0dd81 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/BeanNameViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/BeanNameViewResolver.java @@ -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}. * - *

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. + *

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. * - *

This ViewResolver does not support internationalization. - * Conside ResourceBundleViewResolver if you need to apply different - * view resources per locale. + *

Note: Neither this {@code ViewResolver} nor {@link XmlViewResolver} supports + * internationalization. Consider {@link ResourceBundleViewResolver} if you need + * to apply different view resources per locale. * - *

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. + *

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); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ResourceBundleViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ResourceBundleViewResolver.java index cdb96c751e..c9d71bcb8f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ResourceBundleViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ResourceBundleViewResolver.java @@ -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. * - *

The bundle is typically defined in a properties file, located in - * the class path. The default bundle basename is "views". + *

The bundle is typically defined in a properties file, located in the classpath. + * The default bundle basename is "views". * - *

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". + *

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". * - *

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}. + *

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 *

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; } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/XmlViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/XmlViewResolver.java index 59b45a8a80..890486d62b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/XmlViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/XmlViewResolver.java @@ -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". * - *

This ViewResolver does not support internationalization. - * Consider ResourceBundleViewResolver if you need to apply - * different view resources per locale. + *

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. * - *

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. + *

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; } }