diff --git a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java index 786443bea4e..6faba91e18e 100644 --- a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java +++ b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -28,6 +28,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.core.SpringProperties; import org.springframework.core.convert.support.ConfigurableConversionService; import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import static java.lang.String.*; @@ -103,9 +104,9 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { protected final Log logger = LogFactory.getLog(getClass()); - private Set activeProfiles = new LinkedHashSet(); + private final Set activeProfiles = new LinkedHashSet(); - private Set defaultProfiles = new LinkedHashSet(getReservedDefaultProfiles()); + private final Set defaultProfiles = new LinkedHashSet(getReservedDefaultProfiles()); private final MutablePropertySources propertySources = new MutablePropertySources(this.logger); @@ -236,21 +237,25 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { * @see #ACTIVE_PROFILES_PROPERTY_NAME */ protected Set doGetActiveProfiles() { - if (this.activeProfiles.isEmpty()) { - String profiles = getProperty(ACTIVE_PROFILES_PROPERTY_NAME); - if (StringUtils.hasText(profiles)) { - setActiveProfiles(commaDelimitedListToStringArray(trimAllWhitespace(profiles))); + synchronized (this.activeProfiles) { + if (this.activeProfiles.isEmpty()) { + String profiles = getProperty(ACTIVE_PROFILES_PROPERTY_NAME); + if (StringUtils.hasText(profiles)) { + setActiveProfiles(commaDelimitedListToStringArray(trimAllWhitespace(profiles))); + } } + return this.activeProfiles; } - return this.activeProfiles; } public void setActiveProfiles(String... profiles) { Assert.notNull(profiles, "Profile array must not be null"); - this.activeProfiles.clear(); - for (String profile : profiles) { - validateProfile(profile); - this.activeProfiles.add(profile); + synchronized (this.activeProfiles) { + this.activeProfiles.clear(); + for (String profile : profiles) { + validateProfile(profile); + this.activeProfiles.add(profile); + } } } @@ -260,7 +265,9 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { } validateProfile(profile); doGetActiveProfiles(); - this.activeProfiles.add(profile); + synchronized (this.activeProfiles) { + this.activeProfiles.add(profile); + } } @@ -281,13 +288,15 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { * @see #getReservedDefaultProfiles() */ protected Set doGetDefaultProfiles() { - if (this.defaultProfiles.equals(getReservedDefaultProfiles())) { - String profiles = getProperty(DEFAULT_PROFILES_PROPERTY_NAME); - if (StringUtils.hasText(profiles)) { - setDefaultProfiles(commaDelimitedListToStringArray(trimAllWhitespace(profiles))); + synchronized (this.defaultProfiles) { + if (this.defaultProfiles.equals(getReservedDefaultProfiles())) { + String profiles = getProperty(DEFAULT_PROFILES_PROPERTY_NAME); + if (StringUtils.hasText(profiles)) { + setDefaultProfiles(commaDelimitedListToStringArray(trimAllWhitespace(profiles))); + } } + return this.defaultProfiles; } - return this.defaultProfiles; } /** @@ -300,17 +309,19 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { */ public void setDefaultProfiles(String... profiles) { Assert.notNull(profiles, "Profile array must not be null"); - this.defaultProfiles.clear(); - for (String profile : profiles) { - validateProfile(profile); - this.defaultProfiles.add(profile); + synchronized (this.defaultProfiles) { + this.defaultProfiles.clear(); + for (String profile : profiles) { + validateProfile(profile); + this.defaultProfiles.add(profile); + } } } public boolean acceptsProfiles(String... profiles) { Assert.notEmpty(profiles, "Must specify at least one profile"); for (String profile : profiles) { - if (profile != null && profile.length() > 0 && profile.charAt(0) == '!') { + if (StringUtils.hasLength(profile) && profile.charAt(0) == '!') { if (!isProfileActive(profile.substring(1))) { return true; } @@ -329,8 +340,9 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { */ protected boolean isProfileActive(String profile) { validateProfile(profile); - return doGetActiveProfiles().contains(profile) || - (doGetActiveProfiles().isEmpty() && doGetDefaultProfiles().contains(profile)); + Set currentActiveProfiles = doGetActiveProfiles(); + return (currentActiveProfiles.contains(profile) || + (currentActiveProfiles.isEmpty() && doGetDefaultProfiles().contains(profile))); } /** @@ -430,13 +442,21 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { this.propertySources.addLast(ps); } } - for (String profile : parent.getActiveProfiles()) { - this.activeProfiles.add(profile); + String[] parentActiveProfiles = parent.getActiveProfiles(); + if (!ObjectUtils.isEmpty(parentActiveProfiles)) { + synchronized (this.activeProfiles) { + for (String profile : parentActiveProfiles) { + this.activeProfiles.add(profile); + } + } } - if (parent.getDefaultProfiles().length > 0) { - this.defaultProfiles.remove(RESERVED_DEFAULT_PROFILE_NAME); - for (String profile : parent.getDefaultProfiles()) { - this.defaultProfiles.add(profile); + String[] parentDefaultProfiles = parent.getDefaultProfiles(); + if (!ObjectUtils.isEmpty(parentDefaultProfiles)) { + synchronized (this.defaultProfiles) { + this.defaultProfiles.remove(RESERVED_DEFAULT_PROFILE_NAME); + for (String profile : parentDefaultProfiles) { + this.defaultProfiles.add(profile); + } } } }