Skip to content

Commit 887fa4a

Browse files
committed
Merge branch '2.5.x' into 2.6.x
Closes gh-30664
2 parents 9e98ccd + c8de843 commit 887fa4a

File tree

2 files changed

+64
-6
lines changed

2 files changed

+64
-6
lines changed

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import org.springframework.util.ObjectUtils;
6363
import org.springframework.util.ReflectionUtils;
6464
import org.springframework.util.StringUtils;
65+
import org.springframework.web.context.ConfigurableWebApplicationContext;
6566
import org.springframework.web.context.support.GenericWebApplicationContext;
6667

6768
/**
@@ -113,14 +114,21 @@ public ApplicationContext loadContext(MergedContextConfiguration config) throws
113114
}
114115
else if (config instanceof ReactiveWebMergedContextConfiguration) {
115116
application.setWebApplicationType(WebApplicationType.REACTIVE);
116-
if (!isEmbeddedWebEnvironment(config)) {
117-
application.setApplicationContextFactory(
118-
ApplicationContextFactory.of(GenericReactiveWebApplicationContext::new));
119-
}
120117
}
121118
else {
122119
application.setWebApplicationType(WebApplicationType.NONE);
123120
}
121+
application.setApplicationContextFactory((type) -> {
122+
if (type != WebApplicationType.NONE && !isEmbeddedWebEnvironment(config)) {
123+
if (type == WebApplicationType.REACTIVE) {
124+
return new GenericReactiveWebApplicationContext();
125+
}
126+
else if (type == WebApplicationType.SERVLET) {
127+
return new GenericWebApplicationContext();
128+
}
129+
}
130+
return ApplicationContextFactory.DEFAULT.create(type);
131+
});
124132
application.setInitializers(initializers);
125133
boolean customEnvironent = ReflectionUtils.findMethod(getClass(), "getEnvironment")
126134
.getDeclaringClass() != SpringBootContextLoader.class;
@@ -285,14 +293,38 @@ void configure(MergedContextConfiguration configuration, SpringApplication appli
285293
List<ApplicationContextInitializer<?>> initializers) {
286294
WebMergedContextConfiguration webConfiguration = (WebMergedContextConfiguration) configuration;
287295
addMockServletContext(initializers, webConfiguration);
288-
application.setApplicationContextFactory((webApplicationType) -> new GenericWebApplicationContext());
289296
}
290297

291298
private void addMockServletContext(List<ApplicationContextInitializer<?>> initializers,
292299
WebMergedContextConfiguration webConfiguration) {
293300
SpringBootMockServletContext servletContext = new SpringBootMockServletContext(
294301
webConfiguration.getResourceBasePath());
295-
initializers.add(0, new ServletContextApplicationContextInitializer(servletContext, true));
302+
initializers.add(0, new DefensiveWebApplicationContextInitializer(
303+
new ServletContextApplicationContextInitializer(servletContext, true)));
304+
}
305+
306+
/**
307+
* Decorator for {@link ServletContextApplicationContextInitializer} that prevents
308+
* a failure when the context type is not as was predicted when the initializer
309+
* was registered. This can occur when spring.main.web-application-type is set to
310+
* something other than servlet.
311+
*/
312+
private static final class DefensiveWebApplicationContextInitializer
313+
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
314+
315+
private final ServletContextApplicationContextInitializer delegate;
316+
317+
private DefensiveWebApplicationContextInitializer(ServletContextApplicationContextInitializer delegate) {
318+
this.delegate = delegate;
319+
}
320+
321+
@Override
322+
public void initialize(ConfigurableApplicationContext applicationContext) {
323+
if (applicationContext instanceof ConfigurableWebApplicationContext) {
324+
this.delegate.initialize((ConfigurableWebApplicationContext) applicationContext);
325+
}
326+
}
327+
296328
}
297329

298330
}

spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.junit.jupiter.api.Test;
2525

2626
import org.springframework.boot.test.util.TestPropertyValues;
27+
import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext;
2728
import org.springframework.context.ApplicationContext;
2829
import org.springframework.context.annotation.Configuration;
2930
import org.springframework.core.env.ConfigurableEnvironment;
@@ -36,6 +37,7 @@
3637
import org.springframework.test.context.TestPropertySource;
3738
import org.springframework.test.context.support.TestPropertySourceUtils;
3839
import org.springframework.test.util.ReflectionTestUtils;
40+
import org.springframework.web.context.WebApplicationContext;
3941

4042
import static org.assertj.core.api.Assertions.assertThat;
4143

@@ -146,6 +148,20 @@ void propertySourceOrdering() throws Exception {
146148
assertThat(last).startsWith("Config resource");
147149
}
148150

151+
@Test
152+
void whenEnvironmentChangesWebApplicationTypeToNoneThenContextTypeChangesAccordingly() {
153+
TestContext context = new ExposedTestContextManager(ChangingWebApplicationTypeToNone.class)
154+
.getExposedTestContext();
155+
assertThat(context.getApplicationContext()).isNotInstanceOf(WebApplicationContext.class);
156+
}
157+
158+
@Test
159+
void whenEnvironmentChangesWebApplicationTypeToReactiveThenContextTypeChangesAccordingly() {
160+
TestContext context = new ExposedTestContextManager(ChangingWebApplicationTypeToReactive.class)
161+
.getExposedTestContext();
162+
assertThat(context.getApplicationContext()).isInstanceOf(GenericReactiveWebApplicationContext.class);
163+
}
164+
149165
private String[] getActiveProfiles(Class<?> testClass) {
150166
TestContext testContext = new ExposedTestContextManager(testClass).getExposedTestContext();
151167
ApplicationContext applicationContext = testContext.getApplicationContext();
@@ -228,6 +244,16 @@ static class Config {
228244

229245
}
230246

247+
@SpringBootTest(classes = Config.class, args = "--spring.main.web-application-type=none")
248+
static class ChangingWebApplicationTypeToNone {
249+
250+
}
251+
252+
@SpringBootTest(classes = Config.class, args = "--spring.main.web-application-type=reactive")
253+
static class ChangingWebApplicationTypeToReactive {
254+
255+
}
256+
231257
/**
232258
* {@link TestContextManager} which exposes the {@link TestContext}.
233259
*/

0 commit comments

Comments
 (0)