|
55 | 55 | import org.springframework.util.Assert;
|
56 | 56 | import org.springframework.util.ObjectUtils;
|
57 | 57 | import org.springframework.util.StringUtils;
|
| 58 | +import org.springframework.web.context.ConfigurableWebApplicationContext; |
58 | 59 | import org.springframework.web.context.support.GenericWebApplicationContext;
|
59 | 60 |
|
60 | 61 | /**
|
@@ -103,14 +104,21 @@ public ApplicationContext loadContext(MergedContextConfiguration config) throws
|
103 | 104 | }
|
104 | 105 | else if (config instanceof ReactiveWebMergedContextConfiguration) {
|
105 | 106 | application.setWebApplicationType(WebApplicationType.REACTIVE);
|
106 |
| - if (!isEmbeddedWebEnvironment(config)) { |
107 |
| - application.setApplicationContextFactory( |
108 |
| - ApplicationContextFactory.of(GenericReactiveWebApplicationContext::new)); |
109 |
| - } |
110 | 107 | }
|
111 | 108 | else {
|
112 | 109 | application.setWebApplicationType(WebApplicationType.NONE);
|
113 | 110 | }
|
| 111 | + application.setApplicationContextFactory((type) -> { |
| 112 | + if (type != WebApplicationType.NONE && !isEmbeddedWebEnvironment(config)) { |
| 113 | + if (type == WebApplicationType.REACTIVE) { |
| 114 | + return new GenericReactiveWebApplicationContext(); |
| 115 | + } |
| 116 | + else if (type == WebApplicationType.SERVLET) { |
| 117 | + return new GenericWebApplicationContext(); |
| 118 | + } |
| 119 | + } |
| 120 | + return ApplicationContextFactory.DEFAULT.create(type); |
| 121 | + }); |
114 | 122 | application.setInitializers(initializers);
|
115 | 123 | ConfigurableEnvironment environment = getEnvironment();
|
116 | 124 | if (environment != null) {
|
@@ -261,14 +269,38 @@ void configure(MergedContextConfiguration configuration, SpringApplication appli
|
261 | 269 | List<ApplicationContextInitializer<?>> initializers) {
|
262 | 270 | WebMergedContextConfiguration webConfiguration = (WebMergedContextConfiguration) configuration;
|
263 | 271 | addMockServletContext(initializers, webConfiguration);
|
264 |
| - application.setApplicationContextFactory((webApplicationType) -> new GenericWebApplicationContext()); |
265 | 272 | }
|
266 | 273 |
|
267 | 274 | private void addMockServletContext(List<ApplicationContextInitializer<?>> initializers,
|
268 | 275 | WebMergedContextConfiguration webConfiguration) {
|
269 | 276 | SpringBootMockServletContext servletContext = new SpringBootMockServletContext(
|
270 | 277 | webConfiguration.getResourceBasePath());
|
271 |
| - initializers.add(0, new ServletContextApplicationContextInitializer(servletContext, true)); |
| 278 | + initializers.add(0, new DefensiveWebApplicationContextInitializer( |
| 279 | + new ServletContextApplicationContextInitializer(servletContext, true))); |
| 280 | + } |
| 281 | + |
| 282 | + /** |
| 283 | + * Decorator for {@link ServletContextApplicationContextInitializer} that prevents |
| 284 | + * a failure when the context type is not as was predicted when the initializer |
| 285 | + * was registered. This can occur when spring.main.web-application-type is set to |
| 286 | + * something other than servlet. |
| 287 | + */ |
| 288 | + private static final class DefensiveWebApplicationContextInitializer |
| 289 | + implements ApplicationContextInitializer<ConfigurableApplicationContext> { |
| 290 | + |
| 291 | + private final ServletContextApplicationContextInitializer delegate; |
| 292 | + |
| 293 | + private DefensiveWebApplicationContextInitializer(ServletContextApplicationContextInitializer delegate) { |
| 294 | + this.delegate = delegate; |
| 295 | + } |
| 296 | + |
| 297 | + @Override |
| 298 | + public void initialize(ConfigurableApplicationContext applicationContext) { |
| 299 | + if (applicationContext instanceof ConfigurableWebApplicationContext) { |
| 300 | + this.delegate.initialize((ConfigurableWebApplicationContext) applicationContext); |
| 301 | + } |
| 302 | + } |
| 303 | + |
272 | 304 | }
|
273 | 305 |
|
274 | 306 | }
|
|
0 commit comments