|
62 | 62 | import org.springframework.util.ObjectUtils;
|
63 | 63 | import org.springframework.util.ReflectionUtils;
|
64 | 64 | import org.springframework.util.StringUtils;
|
| 65 | +import org.springframework.web.context.ConfigurableWebApplicationContext; |
65 | 66 | import org.springframework.web.context.support.GenericWebApplicationContext;
|
66 | 67 |
|
67 | 68 | /**
|
@@ -113,14 +114,21 @@ public ApplicationContext loadContext(MergedContextConfiguration config) throws
|
113 | 114 | }
|
114 | 115 | else if (config instanceof ReactiveWebMergedContextConfiguration) {
|
115 | 116 | application.setWebApplicationType(WebApplicationType.REACTIVE);
|
116 |
| - if (!isEmbeddedWebEnvironment(config)) { |
117 |
| - application.setApplicationContextFactory( |
118 |
| - ApplicationContextFactory.of(GenericReactiveWebApplicationContext::new)); |
119 |
| - } |
120 | 117 | }
|
121 | 118 | else {
|
122 | 119 | application.setWebApplicationType(WebApplicationType.NONE);
|
123 | 120 | }
|
| 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 | + }); |
124 | 132 | application.setInitializers(initializers);
|
125 | 133 | boolean customEnvironent = ReflectionUtils.findMethod(getClass(), "getEnvironment")
|
126 | 134 | .getDeclaringClass() != SpringBootContextLoader.class;
|
@@ -285,14 +293,38 @@ void configure(MergedContextConfiguration configuration, SpringApplication appli
|
285 | 293 | List<ApplicationContextInitializer<?>> initializers) {
|
286 | 294 | WebMergedContextConfiguration webConfiguration = (WebMergedContextConfiguration) configuration;
|
287 | 295 | addMockServletContext(initializers, webConfiguration);
|
288 |
| - application.setApplicationContextFactory((webApplicationType) -> new GenericWebApplicationContext()); |
289 | 296 | }
|
290 | 297 |
|
291 | 298 | private void addMockServletContext(List<ApplicationContextInitializer<?>> initializers,
|
292 | 299 | WebMergedContextConfiguration webConfiguration) {
|
293 | 300 | SpringBootMockServletContext servletContext = new SpringBootMockServletContext(
|
294 | 301 | 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 | + |
296 | 328 | }
|
297 | 329 |
|
298 | 330 | }
|
|
0 commit comments