Skip to content

Commit e713e0d

Browse files
committed
Preserve registration order in @activeprofiles
With this commit, bean definition profiles declared via @activeprofiles are once again stored in registration order, in order to support use cases in Spring Boot and other frameworks that depend on the registration order. This effectively reverts the changes made in conjunction with gh-25973. Closes gh-26004
1 parent b4f8fc8 commit e713e0d

File tree

7 files changed

+44
-47
lines changed

7 files changed

+44
-47
lines changed

spring-test/src/main/java/org/springframework/test/context/ActiveProfiles.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -79,7 +79,7 @@
7979
* <p>The default value is {@code true}, which means that a test
8080
* class will <em>inherit</em> bean definition profiles defined by a
8181
* test superclass. Specifically, the bean definition profiles for a test
82-
* class will be added to the list of bean definition profiles
82+
* class will be appended to the list of bean definition profiles
8383
* defined by a test superclass. Thus, subclasses have the option of
8484
* <em>extending</em> the list of bean definition profiles.
8585
* <p>If {@code inheritProfiles} is set to {@code false}, the bean

spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,8 +19,8 @@
1919
import java.io.Serializable;
2020
import java.util.Arrays;
2121
import java.util.Collections;
22+
import java.util.LinkedHashSet;
2223
import java.util.Set;
23-
import java.util.TreeSet;
2424

2525
import org.springframework.context.ApplicationContext;
2626
import org.springframework.context.ApplicationContextInitializer;
@@ -533,8 +533,8 @@ private static String[] processActiveProfiles(@Nullable String[] activeProfiles)
533533
return EMPTY_STRING_ARRAY;
534534
}
535535

536-
// Active profiles must be unique and sorted
537-
Set<String> profilesSet = new TreeSet<>(Arrays.asList(activeProfiles));
536+
// Active profiles must be unique
537+
Set<String> profilesSet = new LinkedHashSet<>(Arrays.asList(activeProfiles));
538538
return StringUtils.toStringArray(profilesSet);
539539
}
540540

spring-test/src/main/java/org/springframework/test/context/support/ActiveProfilesUtils.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616

1717
package org.springframework.test.context.support;
1818

19+
import java.util.ArrayList;
20+
import java.util.Collections;
21+
import java.util.LinkedHashSet;
22+
import java.util.List;
1923
import java.util.Set;
20-
import java.util.TreeSet;
2124

2225
import org.apache.commons.logging.Log;
2326
import org.apache.commons.logging.LogFactory;
@@ -67,7 +70,7 @@ abstract class ActiveProfilesUtils {
6770
static String[] resolveActiveProfiles(Class<?> testClass) {
6871
Assert.notNull(testClass, "Class must not be null");
6972

70-
Set<String> activeProfiles = new TreeSet<>();
73+
List<String[]> profileArrays = new ArrayList<>();
7174

7275
Class<ActiveProfiles> annotationType = ActiveProfiles.class;
7376
AnnotationDescriptor<ActiveProfiles> descriptor =
@@ -106,17 +109,25 @@ static String[] resolveActiveProfiles(Class<?> testClass) {
106109

107110
String[] profiles = resolver.resolve(rootDeclaringClass);
108111
if (!ObjectUtils.isEmpty(profiles)) {
109-
for (String profile : profiles) {
110-
if (StringUtils.hasText(profile)) {
111-
activeProfiles.add(profile.trim());
112-
}
113-
}
112+
profileArrays.add(profiles);
114113
}
115114

116115
descriptor = (annotation.inheritProfiles() ? MetaAnnotationUtils.findAnnotationDescriptor(
117116
rootDeclaringClass.getSuperclass(), annotationType) : null);
118117
}
119118

119+
// Reverse the list so that we can traverse "down" the hierarchy.
120+
Collections.reverse(profileArrays);
121+
122+
Set<String> activeProfiles = new LinkedHashSet<>();
123+
for (String[] profiles : profileArrays) {
124+
for (String profile : profiles) {
125+
if (StringUtils.hasText(profile)) {
126+
activeProfiles.add(profile.trim());
127+
}
128+
}
129+
}
130+
120131
return StringUtils.toStringArray(activeProfiles);
121132
}
122133

spring-test/src/main/java/org/springframework/test/context/support/DefaultActiveProfilesResolver.java

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,13 @@
1616

1717
package org.springframework.test.context.support;
1818

19-
import java.util.Set;
20-
import java.util.TreeSet;
21-
2219
import org.apache.commons.logging.Log;
2320
import org.apache.commons.logging.LogFactory;
2421

2522
import org.springframework.test.context.ActiveProfiles;
2623
import org.springframework.test.context.ActiveProfilesResolver;
2724
import org.springframework.test.util.MetaAnnotationUtils.AnnotationDescriptor;
2825
import org.springframework.util.Assert;
29-
import org.springframework.util.StringUtils;
3026

3127
import static org.springframework.test.util.MetaAnnotationUtils.findAnnotationDescriptor;
3228

@@ -43,6 +39,8 @@
4339
*/
4440
public class DefaultActiveProfilesResolver implements ActiveProfilesResolver {
4541

42+
private static final String[] EMPTY_STRING_ARRAY = new String[0];
43+
4644
private static final Log logger = LogFactory.getLog(DefaultActiveProfilesResolver.class);
4745

4846

@@ -58,36 +56,24 @@ public class DefaultActiveProfilesResolver implements ActiveProfilesResolver {
5856
@Override
5957
public String[] resolve(Class<?> testClass) {
6058
Assert.notNull(testClass, "Class must not be null");
61-
62-
Set<String> activeProfiles = new TreeSet<>();
63-
64-
Class<ActiveProfiles> annotationType = ActiveProfiles.class;
65-
AnnotationDescriptor<ActiveProfiles> descriptor = findAnnotationDescriptor(testClass, annotationType);
59+
AnnotationDescriptor<ActiveProfiles> descriptor = findAnnotationDescriptor(testClass, ActiveProfiles.class);
6660

6761
if (descriptor == null) {
6862
if (logger.isDebugEnabled()) {
6963
logger.debug(String.format(
7064
"Could not find an 'annotation declaring class' for annotation type [%s] and class [%s]",
71-
annotationType.getName(), testClass.getName()));
65+
ActiveProfiles.class.getName(), testClass.getName()));
7266
}
67+
return EMPTY_STRING_ARRAY;
7368
}
7469
else {
75-
Class<?> declaringClass = descriptor.getDeclaringClass();
7670
ActiveProfiles annotation = descriptor.synthesizeAnnotation();
77-
7871
if (logger.isTraceEnabled()) {
7972
logger.trace(String.format("Retrieved @ActiveProfiles [%s] for declaring class [%s].", annotation,
80-
declaringClass.getName()));
81-
}
82-
83-
for (String profile : annotation.profiles()) {
84-
if (StringUtils.hasText(profile)) {
85-
activeProfiles.add(profile.trim());
86-
}
73+
descriptor.getDeclaringClass().getName()));
8774
}
75+
return annotation.profiles();
8876
}
89-
90-
return StringUtils.toStringArray(activeProfiles);
9177
}
9278

9379
}

spring-test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -143,7 +143,7 @@ void hashCodeWithSameProfilesReversed() {
143143
EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, activeProfiles1, loader);
144144
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(),
145145
EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, activeProfiles2, loader);
146-
assertThat(mergedConfig2).hasSameHashCodeAs(mergedConfig1);
146+
assertThat(mergedConfig2.hashCode()).isNotEqualTo(mergedConfig1.hashCode());
147147
}
148148

149149
@Test
@@ -339,7 +339,7 @@ void equalsWithSameProfilesReversed() {
339339
EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, activeProfiles1, loader);
340340
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(),
341341
EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, activeProfiles2, loader);
342-
assertThat(mergedConfig2).isEqualTo(mergedConfig1);
342+
assertThat(mergedConfig2).isNotEqualTo(mergedConfig1);
343343
}
344344

345345
@Test

spring-test/src/test/java/org/springframework/test/context/cache/ContextCacheTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -90,8 +90,8 @@ void verifyCacheKeyIsBasedOnActiveProfiles() {
9090
int size = 0, hit = 0, miss = 0;
9191
loadCtxAndAssertStats(FooBarProfilesTestCase.class, ++size, hit, ++miss);
9292
loadCtxAndAssertStats(FooBarProfilesTestCase.class, size, ++hit, miss);
93-
// Profiles {foo, bar} MUST hash to the same as {bar, foo}
94-
loadCtxAndAssertStats(BarFooProfilesTestCase.class, size, ++hit, miss);
93+
// Profiles {foo, bar} should not hash to the same as {bar,foo}
94+
loadCtxAndAssertStats(BarFooProfilesTestCase.class, ++size, hit, ++miss);
9595
loadCtxAndAssertStats(FooBarProfilesTestCase.class, size, ++hit, miss);
9696
loadCtxAndAssertStats(FooBarProfilesTestCase.class, size, ++hit, miss);
9797
loadCtxAndAssertStats(BarFooProfilesTestCase.class, size, ++hit, miss);

spring-test/src/test/java/org/springframework/test/context/support/ActiveProfilesUtilsTests.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ void resolveActiveProfilesWithEmptyProfiles() {
6767

6868
@Test
6969
void resolveActiveProfilesWithDuplicatedProfiles() {
70-
assertResolvedProfiles(DuplicatedProfiles.class, "bar", "baz", "foo");
70+
assertResolvedProfiles(DuplicatedProfiles.class, "foo", "bar", "baz");
7171
}
7272

7373
@Test
7474
void resolveActiveProfilesWithLocalAndInheritedDuplicatedProfiles() {
75-
assertResolvedProfiles(ExtendedDuplicatedProfiles.class, "bar", "baz", "cat", "dog", "foo");
75+
assertResolvedProfiles(ExtendedDuplicatedProfiles.class, "foo", "bar", "baz", "cat", "dog");
7676
}
7777

7878
@Test
@@ -92,12 +92,12 @@ void resolveActiveProfilesWithInheritedAnnotationAndClasses() {
9292

9393
@Test
9494
void resolveActiveProfilesWithLocalAndInheritedAnnotations() {
95-
assertResolvedProfiles(LocationsBar.class, "bar", "foo");
95+
assertResolvedProfiles(LocationsBar.class, "foo", "bar");
9696
}
9797

9898
@Test
9999
void resolveActiveProfilesWithOverriddenAnnotation() {
100-
assertResolvedProfiles(Animals.class, "cat", "dog");
100+
assertResolvedProfiles(Animals.class, "dog", "cat");
101101
}
102102

103103
/**
@@ -129,15 +129,15 @@ void resolveActiveProfilesWithMetaAnnotationAndOverriddenAttributes() {
129129
*/
130130
@Test
131131
void resolveActiveProfilesWithLocalAndInheritedMetaAnnotations() {
132-
assertResolvedProfiles(MetaLocationsBar.class, "bar", "foo");
132+
assertResolvedProfiles(MetaLocationsBar.class, "foo", "bar");
133133
}
134134

135135
/**
136136
* @since 4.0
137137
*/
138138
@Test
139139
void resolveActiveProfilesWithOverriddenMetaAnnotation() {
140-
assertResolvedProfiles(MetaAnimals.class, "cat", "dog");
140+
assertResolvedProfiles(MetaAnimals.class, "dog", "cat");
141141
}
142142

143143
/**
@@ -161,7 +161,7 @@ void resolveActiveProfilesWithInheritedResolver() {
161161
*/
162162
@Test
163163
void resolveActiveProfilesWithMergedInheritedResolver() {
164-
assertResolvedProfiles(MergedInheritedFooActiveProfilesResolverTestCase.class, "bar", "foo");
164+
assertResolvedProfiles(MergedInheritedFooActiveProfilesResolverTestCase.class, "foo", "bar");
165165
}
166166

167167
/**

0 commit comments

Comments
 (0)