AbstractEnvironment defensively synchronizes access to activeProfiles and defaultProfiles
Issue: SPR-13213
This commit is contained in:
parent
e214e64782
commit
e393c7b1ee
|
@ -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<String> activeProfiles = new LinkedHashSet<String>();
|
||||
private final Set<String> activeProfiles = new LinkedHashSet<String>();
|
||||
|
||||
private Set<String> defaultProfiles = new LinkedHashSet<String>(getReservedDefaultProfiles());
|
||||
private final Set<String> defaultProfiles = new LinkedHashSet<String>(getReservedDefaultProfiles());
|
||||
|
||||
private final MutablePropertySources propertySources = new MutablePropertySources(this.logger);
|
||||
|
||||
|
@ -237,22 +238,26 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||
* @see #ACTIVE_PROFILES_PROPERTY_NAME
|
||||
*/
|
||||
protected Set<String> 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,7 +268,9 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||
}
|
||||
validateProfile(profile);
|
||||
doGetActiveProfiles();
|
||||
this.activeProfiles.add(profile);
|
||||
synchronized (this.activeProfiles) {
|
||||
this.activeProfiles.add(profile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -285,13 +292,15 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||
* @see #getReservedDefaultProfiles()
|
||||
*/
|
||||
protected Set<String> 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -305,10 +314,12 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,7 +327,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||
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;
|
||||
}
|
||||
|
@ -335,8 +346,9 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||
*/
|
||||
protected boolean isProfileActive(String profile) {
|
||||
validateProfile(profile);
|
||||
return doGetActiveProfiles().contains(profile) ||
|
||||
(doGetActiveProfiles().isEmpty() && doGetDefaultProfiles().contains(profile));
|
||||
Set<String> currentActiveProfiles = doGetActiveProfiles();
|
||||
return (currentActiveProfiles.contains(profile) ||
|
||||
(currentActiveProfiles.isEmpty() && doGetDefaultProfiles().contains(profile)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -364,7 +376,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public Map<String, Object> getSystemEnvironment() {
|
||||
if (suppressGetenvAccess()) {
|
||||
return Collections.emptyMap();
|
||||
|
@ -408,7 +420,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public Map<String, Object> getSystemProperties() {
|
||||
try {
|
||||
return (Map) System.getProperties();
|
||||
|
@ -440,13 +452,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue