18
18
19
19
import java .util .ArrayList ;
20
20
import java .util .Arrays ;
21
+ import java .util .Collections ;
21
22
import java .util .List ;
22
23
23
24
import org .springframework .beans .BeanUtils ;
24
25
import org .springframework .boot .ApplicationContextFactory ;
26
+ import org .springframework .boot .DefaultPropertiesPropertySource ;
25
27
import org .springframework .boot .SpringApplication ;
26
28
import org .springframework .boot .WebApplicationType ;
29
+ import org .springframework .boot .context .event .ApplicationEnvironmentPreparedEvent ;
27
30
import org .springframework .boot .test .context .SpringBootTest .WebEnvironment ;
28
31
import org .springframework .boot .test .mock .web .SpringBootMockServletContext ;
29
32
import org .springframework .boot .test .util .TestPropertyValues ;
32
35
import org .springframework .boot .web .servlet .support .ServletContextApplicationContextInitializer ;
33
36
import org .springframework .context .ApplicationContext ;
34
37
import org .springframework .context .ApplicationContextInitializer ;
38
+ import org .springframework .context .ApplicationListener ;
35
39
import org .springframework .context .ConfigurableApplicationContext ;
36
40
import org .springframework .core .Ordered ;
41
+ import org .springframework .core .PriorityOrdered ;
37
42
import org .springframework .core .SpringVersion ;
38
43
import org .springframework .core .annotation .MergedAnnotations ;
39
44
import org .springframework .core .annotation .MergedAnnotations .SearchStrategy ;
40
45
import org .springframework .core .annotation .Order ;
46
+ import org .springframework .core .env .CommandLinePropertySource ;
41
47
import org .springframework .core .env .ConfigurableEnvironment ;
42
- import org .springframework .core .env .Environment ;
48
+ import org .springframework .core .env .MutablePropertySources ;
49
+ import org .springframework .core .env .PropertySource ;
43
50
import org .springframework .core .env .StandardEnvironment ;
44
51
import org .springframework .core .io .DefaultResourceLoader ;
45
52
import org .springframework .core .io .ResourceLoader ;
53
60
import org .springframework .test .context .web .WebMergedContextConfiguration ;
54
61
import org .springframework .util .Assert ;
55
62
import org .springframework .util .ObjectUtils ;
63
+ import org .springframework .util .ReflectionUtils ;
56
64
import org .springframework .util .StringUtils ;
57
65
import org .springframework .web .context .support .GenericWebApplicationContext ;
58
66
81
89
*/
82
90
public class SpringBootContextLoader extends AbstractContextLoader {
83
91
92
+ private static final String [] PRIORITY_PROPERTY_SOURCES = { "configurationProperties" ,
93
+ DefaultPropertiesPropertySource .NAME , CommandLinePropertySource .COMMAND_LINE_PROPERTY_SOURCE_NAME };
94
+
84
95
@ Override
85
96
public ApplicationContext loadContext (MergedContextConfiguration config ) throws Exception {
86
97
Class <?>[] configClasses = config .getClasses ();
@@ -111,23 +122,49 @@ else if (config instanceof ReactiveWebMergedContextConfiguration) {
111
122
application .setWebApplicationType (WebApplicationType .NONE );
112
123
}
113
124
application .setInitializers (initializers );
114
- ConfigurableEnvironment environment = getEnvironment ();
115
- setActiveProfiles (environment , config .getActiveProfiles ());
125
+ boolean customEnvironent = ReflectionUtils .findMethod (getClass (), "getEnvironment" )
126
+ .getDeclaringClass () != SpringBootContextLoader .class ;
127
+ if (customEnvironent ) {
128
+ ConfigurableEnvironment environment = getEnvironment ();
129
+ prepareEnvironment (config , application , environment , false );
130
+ application .setEnvironment (environment );
131
+ }
132
+ else {
133
+ application .addListeners (new PrepareEnvironmentListener (config ));
134
+ }
135
+ String [] args = SpringBootTestArgs .get (config .getContextCustomizers ());
136
+ return application .run (args );
137
+ }
138
+
139
+ private void prepareEnvironment (MergedContextConfiguration config , SpringApplication application ,
140
+ ConfigurableEnvironment environment , boolean applicationEnvironment ) {
141
+ MutablePropertySources propertySources = environment .getPropertySources ();
142
+ List <PropertySource <?>> priorityPropertySources = new ArrayList <>();
143
+ if (applicationEnvironment ) {
144
+ for (String priorityPropertySourceName : PRIORITY_PROPERTY_SOURCES ) {
145
+ PropertySource <?> priorityPropertySource = propertySources .get (priorityPropertySourceName );
146
+ if (priorityPropertySource != null ) {
147
+ priorityPropertySources .add (priorityPropertySource );
148
+ propertySources .remove (priorityPropertySourceName );
149
+ }
150
+ }
151
+ }
152
+ setActiveProfiles (environment , config .getActiveProfiles (), applicationEnvironment );
116
153
ResourceLoader resourceLoader = (application .getResourceLoader () != null ) ? application .getResourceLoader ()
117
154
: new DefaultResourceLoader (null );
118
155
TestPropertySourceUtils .addPropertiesFilesToEnvironment (environment , resourceLoader ,
119
156
config .getPropertySourceLocations ());
120
157
TestPropertySourceUtils .addInlinedPropertiesToEnvironment (environment , getInlinedProperties (config ));
121
- application .setEnvironment (environment );
122
- String [] args = SpringBootTestArgs .get (config .getContextCustomizers ());
123
- return application .run (args );
158
+ Collections .reverse (priorityPropertySources );
159
+ priorityPropertySources .forEach (propertySources ::addFirst );
124
160
}
125
161
126
- private void setActiveProfiles (ConfigurableEnvironment environment , String [] profiles ) {
162
+ private void setActiveProfiles (ConfigurableEnvironment environment , String [] profiles ,
163
+ boolean applicationEnvironment ) {
127
164
if (ObjectUtils .isEmpty (profiles )) {
128
165
return ;
129
166
}
130
- if (!( environment instanceof TestEnvironment ) ) {
167
+ if (!applicationEnvironment ) {
131
168
environment .setActiveProfiles (profiles );
132
169
}
133
170
String [] pairs = new String [profiles .length ];
@@ -152,7 +189,7 @@ protected SpringApplication getSpringApplication() {
152
189
* @return a {@link ConfigurableEnvironment} instance
153
190
*/
154
191
protected ConfigurableEnvironment getEnvironment () {
155
- return new TestEnvironment ();
192
+ return new StandardEnvironment ();
156
193
}
157
194
158
195
protected String [] getInlinedProperties (MergedContextConfiguration config ) {
@@ -304,19 +341,25 @@ public void initialize(ConfigurableApplicationContext applicationContext) {
304
341
}
305
342
306
343
/**
307
- * Side-effect free {@link Environment} that doesn't set profiles directly from
308
- * properties.
344
+ * {@link ApplicationListener} used to prepare the application created environment.
309
345
*/
310
- static class TestEnvironment extends StandardEnvironment {
346
+ private class PrepareEnvironmentListener
347
+ implements ApplicationListener <ApplicationEnvironmentPreparedEvent >, PriorityOrdered {
348
+
349
+ private final MergedContextConfiguration config ;
350
+
351
+ PrepareEnvironmentListener (MergedContextConfiguration config ) {
352
+ this .config = config ;
353
+ }
311
354
312
355
@ Override
313
- protected String doGetActiveProfilesProperty () {
314
- return null ;
356
+ public int getOrder () {
357
+ return Ordered . HIGHEST_PRECEDENCE ;
315
358
}
316
359
317
360
@ Override
318
- protected String doGetDefaultProfilesProperty ( ) {
319
- return null ;
361
+ public void onApplicationEvent ( ApplicationEnvironmentPreparedEvent event ) {
362
+ prepareEnvironment ( this . config , event . getSpringApplication (), event . getEnvironment (), true ) ;
320
363
}
321
364
322
365
}
0 commit comments