diff --git a/org.springframework.core/src/main/java/org/springframework/core/env/AbstractEnvironment.java b/org.springframework.core/src/main/java/org/springframework/core/env/AbstractEnvironment.java index fcc067619d..4e93c5a278 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/env/AbstractEnvironment.java +++ b/org.springframework.core/src/main/java/org/springframework/core/env/AbstractEnvironment.java @@ -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. @@ -16,11 +16,8 @@ package org.springframework.core.env; -import static java.lang.String.format; -import static org.springframework.util.StringUtils.commaDelimitedListToStringArray; -import static org.springframework.util.StringUtils.trimAllWhitespace; - import java.security.AccessControlException; + import java.util.Collections; import java.util.LinkedHashSet; import java.util.Map; @@ -28,10 +25,14 @@ import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.core.convert.support.ConfigurableConversionService; import org.springframework.util.Assert; import org.springframework.util.StringUtils; +import static java.lang.String.*; +import static org.springframework.util.StringUtils.*; + /** * Abstract base class for {@link Environment} implementations. Supports the notion of * reserved default profile names and enables specifying active and default profiles @@ -89,19 +90,39 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { protected final Log logger = LogFactory.getLog(getClass()); private Set activeProfiles = new LinkedHashSet(); - private Set defaultProfiles = new LinkedHashSet(this.getReservedDefaultProfiles()); - private final MutablePropertySources propertySources = new MutablePropertySources(logger); - private final ConfigurablePropertyResolver propertyResolver = new PropertySourcesPropertyResolver(propertySources); + private Set defaultProfiles = + new LinkedHashSet(this.getReservedDefaultProfiles()); + + private final MutablePropertySources propertySources = + new MutablePropertySources(this.logger); + + private final ConfigurablePropertyResolver propertyResolver = + new PropertySourcesPropertyResolver(this.propertySources); + /** + * Create a new {@code Environment} instance, calling back to + * {@link #customizePropertySources(MutablePropertySources)} during construction to + * allow subclasses to contribute or manipulate {@link PropertySource} instances as + * appropriate. + * @see #customizePropertySources(MutablePropertySources) + */ public AbstractEnvironment() { String name = this.getClass().getSimpleName(); - logger.debug(String.format("Initializing new %s", name)); - this.customizePropertySources(propertySources); - logger.debug(String.format("Initialized %s with PropertySources %s", name, propertySources)); + if (this.logger.isDebugEnabled()) { + this.logger.debug(format("Initializing new %s", name)); + } + + this.customizePropertySources(this.propertySources); + + if (this.logger.isDebugEnabled()) { + this.logger.debug(format( + "Initialized %s with PropertySources %s", name, this.propertySources)); + } } + /** * Customize the set of {@link PropertySource} objects to be searched by this * {@code Environment} during calls to {@link #getProperty(String)} and related @@ -163,6 +184,17 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { * env.getPropertySources().addLast(new PropertySourceX(...)); * * + *

A warning about instance variable access

+ * Instance variables declared in subclasses and having default initial values should + * not be accessed from within this method. Due to Java object creation + * lifecycle constraints, any initial value will not yet be assigned when this + * callback is invoked by the {@link #AbstractEnvironment()} constructor, which may + * lead to a {@code NullPointerException} or other problems. If you need to access + * default values of instance variables, leave this method as a no-op and perform + * property source manipulation and instance variable access directly within the + * subclass constructor. Note that assigning values to instance variables is + * not problematic; it is only attempting to read default values that must be avoided. + * * @see MutablePropertySources * @see PropertySourcesPropertyResolver * @see org.springframework.context.ApplicationContextInitializer @@ -217,7 +249,9 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { } public void addActiveProfile(String profile) { - logger.debug(String.format("Activating profile '%s'", profile)); + if (this.logger.isDebugEnabled()) { + this.logger.debug(format("Activating profile '%s'", profile)); + } this.validateProfile(profile); this.activeProfiles.add(profile); } @@ -312,8 +346,10 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { } catch (AccessControlException ex) { if (logger.isInfoEnabled()) { - logger.info(format("Caught AccessControlException when accessing system environment variable " + - "[%s]; its value will be returned [null]. Reason: %s", variableName, ex.getMessage())); + logger.info(format("Caught AccessControlException when " + + "accessing system environment variable [%s]; its " + + "value will be returned [null]. Reason: %s", + variableName, ex.getMessage())); } return null; } @@ -338,8 +374,10 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { } catch (AccessControlException ex) { if (logger.isInfoEnabled()) { - logger.info(format("Caught AccessControlException when accessing system property " + - "[%s]; its value will be returned [null]. Reason: %s", propertyName, ex.getMessage())); + logger.info(format("Caught AccessControlException when " + + "accessing system property [%s]; its value will be " + + "returned [null]. Reason: %s", + propertyName, ex.getMessage())); } return null; } @@ -428,7 +466,8 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { @Override public String toString() { return format("%s {activeProfiles=%s, defaultProfiles=%s, propertySources=%s}", - getClass().getSimpleName(), this.activeProfiles, this.defaultProfiles, this.propertySources); + getClass().getSimpleName(), this.activeProfiles, this.defaultProfiles, + this.propertySources); } }