Browse Source

AbstractEnvironment defensively synchronizes access to activeProfiles and defaultProfiles

Issue: SPR-13213
(cherry picked from commit af5f4e6)
pull/1057/head
Juergen Hoeller 10 years ago
parent
commit
d2447ce523
  1. 82
      spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java

82
spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java vendored

@ -1,5 +1,5 @@ @@ -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; @@ -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 { @@ -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);
@ -236,21 +237,25 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { @@ -236,21 +237,25 @@ 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;
}
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 { @@ -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 { @@ -281,13 +288,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;
}
/**
@ -300,17 +309,19 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { @@ -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 { @@ -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<String> currentActiveProfiles = doGetActiveProfiles();
return (currentActiveProfiles.contains(profile) ||
(currentActiveProfiles.isEmpty() && doGetDefaultProfiles().contains(profile)));
}
/**
@ -430,13 +442,21 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { @@ -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);
}
}
}
}

Loading…
Cancel
Save