AbstractEnvironment defensively synchronizes access to activeProfiles and defaultProfiles
Issue: SPR-13213
(cherry picked from commit e393c7b)
This commit is contained in:
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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.SpringProperties;
|
||||||
import org.springframework.core.convert.support.ConfigurableConversionService;
|
import org.springframework.core.convert.support.ConfigurableConversionService;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import static java.lang.String.*;
|
import static java.lang.String.*;
|
||||||
@@ -103,9 +104,9 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||||||
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
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);
|
private final MutablePropertySources propertySources = new MutablePropertySources(this.logger);
|
||||||
|
|
||||||
@@ -237,22 +238,26 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||||||
* @see #ACTIVE_PROFILES_PROPERTY_NAME
|
* @see #ACTIVE_PROFILES_PROPERTY_NAME
|
||||||
*/
|
*/
|
||||||
protected Set<String> doGetActiveProfiles() {
|
protected Set<String> doGetActiveProfiles() {
|
||||||
if (this.activeProfiles.isEmpty()) {
|
synchronized (this.activeProfiles) {
|
||||||
String profiles = getProperty(ACTIVE_PROFILES_PROPERTY_NAME);
|
if (this.activeProfiles.isEmpty()) {
|
||||||
if (StringUtils.hasText(profiles)) {
|
String profiles = getProperty(ACTIVE_PROFILES_PROPERTY_NAME);
|
||||||
setActiveProfiles(commaDelimitedListToStringArray(trimAllWhitespace(profiles)));
|
if (StringUtils.hasText(profiles)) {
|
||||||
|
setActiveProfiles(commaDelimitedListToStringArray(trimAllWhitespace(profiles)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return this.activeProfiles;
|
||||||
}
|
}
|
||||||
return this.activeProfiles;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setActiveProfiles(String... profiles) {
|
public void setActiveProfiles(String... profiles) {
|
||||||
Assert.notNull(profiles, "Profile array must not be null");
|
Assert.notNull(profiles, "Profile array must not be null");
|
||||||
this.activeProfiles.clear();
|
synchronized (this.activeProfiles) {
|
||||||
for (String profile : profiles) {
|
this.activeProfiles.clear();
|
||||||
validateProfile(profile);
|
for (String profile : profiles) {
|
||||||
this.activeProfiles.add(profile);
|
validateProfile(profile);
|
||||||
|
this.activeProfiles.add(profile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,7 +268,9 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||||||
}
|
}
|
||||||
validateProfile(profile);
|
validateProfile(profile);
|
||||||
doGetActiveProfiles();
|
doGetActiveProfiles();
|
||||||
this.activeProfiles.add(profile);
|
synchronized (this.activeProfiles) {
|
||||||
|
this.activeProfiles.add(profile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -285,13 +292,15 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||||||
* @see #getReservedDefaultProfiles()
|
* @see #getReservedDefaultProfiles()
|
||||||
*/
|
*/
|
||||||
protected Set<String> doGetDefaultProfiles() {
|
protected Set<String> doGetDefaultProfiles() {
|
||||||
if (this.defaultProfiles.equals(getReservedDefaultProfiles())) {
|
synchronized (this.defaultProfiles) {
|
||||||
String profiles = getProperty(DEFAULT_PROFILES_PROPERTY_NAME);
|
if (this.defaultProfiles.equals(getReservedDefaultProfiles())) {
|
||||||
if (StringUtils.hasText(profiles)) {
|
String profiles = getProperty(DEFAULT_PROFILES_PROPERTY_NAME);
|
||||||
setDefaultProfiles(commaDelimitedListToStringArray(trimAllWhitespace(profiles)));
|
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
|
@Override
|
||||||
public void setDefaultProfiles(String... profiles) {
|
public void setDefaultProfiles(String... profiles) {
|
||||||
Assert.notNull(profiles, "Profile array must not be null");
|
Assert.notNull(profiles, "Profile array must not be null");
|
||||||
this.defaultProfiles.clear();
|
synchronized (this.defaultProfiles) {
|
||||||
for (String profile : profiles) {
|
this.defaultProfiles.clear();
|
||||||
validateProfile(profile);
|
for (String profile : profiles) {
|
||||||
this.defaultProfiles.add(profile);
|
validateProfile(profile);
|
||||||
|
this.defaultProfiles.add(profile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +327,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||||||
public boolean acceptsProfiles(String... profiles) {
|
public boolean acceptsProfiles(String... profiles) {
|
||||||
Assert.notEmpty(profiles, "Must specify at least one profile");
|
Assert.notEmpty(profiles, "Must specify at least one profile");
|
||||||
for (String profile : profiles) {
|
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))) {
|
if (!isProfileActive(profile.substring(1))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -335,8 +346,9 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||||||
*/
|
*/
|
||||||
protected boolean isProfileActive(String profile) {
|
protected boolean isProfileActive(String profile) {
|
||||||
validateProfile(profile);
|
validateProfile(profile);
|
||||||
return doGetActiveProfiles().contains(profile) ||
|
Set<String> currentActiveProfiles = doGetActiveProfiles();
|
||||||
(doGetActiveProfiles().isEmpty() && doGetDefaultProfiles().contains(profile));
|
return (currentActiveProfiles.contains(profile) ||
|
||||||
|
(currentActiveProfiles.isEmpty() && doGetDefaultProfiles().contains(profile)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -364,7 +376,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public Map<String, Object> getSystemEnvironment() {
|
public Map<String, Object> getSystemEnvironment() {
|
||||||
if (suppressGetenvAccess()) {
|
if (suppressGetenvAccess()) {
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
@@ -408,7 +420,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public Map<String, Object> getSystemProperties() {
|
public Map<String, Object> getSystemProperties() {
|
||||||
try {
|
try {
|
||||||
return (Map) System.getProperties();
|
return (Map) System.getProperties();
|
||||||
@@ -440,13 +452,21 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||||||
this.propertySources.addLast(ps);
|
this.propertySources.addLast(ps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (String profile : parent.getActiveProfiles()) {
|
String[] parentActiveProfiles = parent.getActiveProfiles();
|
||||||
this.activeProfiles.add(profile);
|
if (!ObjectUtils.isEmpty(parentActiveProfiles)) {
|
||||||
|
synchronized (this.activeProfiles) {
|
||||||
|
for (String profile : parentActiveProfiles) {
|
||||||
|
this.activeProfiles.add(profile);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (parent.getDefaultProfiles().length > 0) {
|
String[] parentDefaultProfiles = parent.getDefaultProfiles();
|
||||||
this.defaultProfiles.remove(RESERVED_DEFAULT_PROFILE_NAME);
|
if (!ObjectUtils.isEmpty(parentDefaultProfiles)) {
|
||||||
for (String profile : parent.getDefaultProfiles()) {
|
synchronized (this.defaultProfiles) {
|
||||||
this.defaultProfiles.add(profile);
|
this.defaultProfiles.remove(RESERVED_DEFAULT_PROFILE_NAME);
|
||||||
|
for (String profile : parentDefaultProfiles) {
|
||||||
|
this.defaultProfiles.add(profile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user