From deaa6089b0019da0f4ada042da91c857c46d1551 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 28 Feb 2017 15:18:23 +0100 Subject: [PATCH] Move `HttpHandler` configuration to a dedicated auto-configuration An `HttpHandler` bean must be provided once the infrastructure triggered by `@EnableWebFlux` has been processed. Rather than creating a `HttpHandler` in that auto-configuration, this commit moves it to a dedicated auto-config, like we do for `DispatcherServlet` for servlet-based webapps. As this is the only bean we auto-configure in a functional fashion, the `WebFluxFunctionalAutoConfiguration` is now merged with this new auto-configuration, making its purposes clearer. Cloess gh-8436 --- ...java => HttpHandlerAutoConfiguration.java} | 52 +++++-- .../WebFluxAnnotationAutoConfiguration.java | 29 +--- .../main/resources/META-INF/spring.factories | 2 +- ...=> HttpHandlerAutoConfigurationTests.java} | 85 +++++++---- ...bFluxAnnotationAutoConfigurationTests.java | 138 +++++++----------- 5 files changed, 150 insertions(+), 156 deletions(-) rename spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/{WebFluxFunctionalAutoConfiguration.java => HttpHandlerAutoConfiguration.java} (72%) rename spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/{WebFluxFunctionalAutoConfigurationTests.java => HttpHandlerAutoConfigurationTests.java} (60%) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/WebFluxFunctionalAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/HttpHandlerAutoConfiguration.java similarity index 72% rename from spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/WebFluxFunctionalAutoConfiguration.java rename to spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/HttpHandlerAutoConfiguration.java index 5fa8df80804..774a7d99cab 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/WebFluxFunctionalAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/HttpHandlerAutoConfiguration.java @@ -16,7 +16,6 @@ package org.springframework.boot.autoconfigure.webflux; -import java.util.Collections; import java.util.List; import org.springframework.beans.factory.ObjectProvider; @@ -27,6 +26,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -45,21 +45,40 @@ import org.springframework.web.server.adapter.WebHttpHandlerBuilder; import org.springframework.web.server.session.WebSessionManager; /** - * {@link EnableAutoConfiguration Auto-configuration} for Functional WebFlux. + * {@link EnableAutoConfiguration Auto-configuration} for {@link HttpHandler}. * * @author Brian Clozel + * @author Stephane Nicoll */ @Configuration -@ConditionalOnClass({DispatcherHandler.class, HttpHandler.class}) +@ConditionalOnClass({ DispatcherHandler.class, HttpHandler.class }) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) -@ConditionalOnBean(RouterFunction.class) @ConditionalOnMissingBean(HttpHandler.class) -@AutoConfigureAfter({ReactiveWebServerAutoConfiguration.class}) +@AutoConfigureAfter({ WebFluxAnnotationAutoConfiguration.class }) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) -public class WebFluxFunctionalAutoConfiguration { +public class HttpHandlerAutoConfiguration { @Configuration - public static class WebFluxFunctionalConfig { + @ConditionalOnMissingBean(RouterFunction.class) + public static class AnnotationConfig { + + private ApplicationContext applicationContext; + + public AnnotationConfig(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + @Bean + public HttpHandler httpHandler() { + return WebHttpHandlerBuilder.applicationContext(this.applicationContext) + .build(); + } + + } + + @Configuration + @ConditionalOnBean(RouterFunction.class) + public static class FunctionalConfig { private final List webFilters; @@ -71,7 +90,7 @@ public class WebFluxFunctionalAutoConfiguration { private final List viewResolvers; - public WebFluxFunctionalConfig(ObjectProvider> webFilters, + public FunctionalConfig(ObjectProvider> webFilters, ObjectProvider webSessionManager, ObjectProvider> messageReaders, ObjectProvider> messageWriters, @@ -88,24 +107,27 @@ public class WebFluxFunctionalAutoConfiguration { @Bean public HttpHandler httpHandler(List routerFunctions) { - Collections.sort(routerFunctions, new AnnotationAwareOrderComparator()); - RouterFunction routerFunction = routerFunctions.stream().reduce(RouterFunction::and).get(); + routerFunctions.sort(new AnnotationAwareOrderComparator()); + RouterFunction routerFunction = routerFunctions.stream() + .reduce(RouterFunction::and).get(); HandlerStrategies.Builder strategiesBuilder = HandlerStrategies.builder(); if (this.messageReaders != null) { - this.messageReaders.forEach(reader -> strategiesBuilder.messageReader(reader)); + this.messageReaders.forEach(strategiesBuilder::messageReader); } if (this.messageWriters != null) { - this.messageWriters.forEach(writer -> strategiesBuilder.messageWriter(writer)); + this.messageWriters.forEach(strategiesBuilder::messageWriter); } if (this.viewResolvers != null) { - this.viewResolvers.forEach(viewResolver -> strategiesBuilder.viewResolver(viewResolver)); + this.viewResolvers.forEach(strategiesBuilder::viewResolver); } - WebHandler webHandler = RouterFunctions.toHttpHandler(routerFunction, strategiesBuilder.build()); + WebHandler webHandler = RouterFunctions + .toHttpHandler(routerFunction, strategiesBuilder.build()); WebHttpHandlerBuilder builder = WebHttpHandlerBuilder .webHandler(webHandler) .sessionManager(this.webSessionManager); if (this.webFilters != null) { - builder.filters(this.webFilters.toArray(new WebFilter[this.webFilters.size()])); + builder.filters(this.webFilters.toArray( + new WebFilter[this.webFilters.size()])); } return builder.build(); } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/WebFluxAnnotationAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/WebFluxAnnotationAutoConfiguration.java index e669176a878..5b675200b63 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/WebFluxAnnotationAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/WebFluxAnnotationAutoConfiguration.java @@ -23,7 +23,6 @@ import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; @@ -36,8 +35,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain; import org.springframework.boot.autoconfigure.web.ResourceProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -48,8 +45,6 @@ import org.springframework.core.convert.converter.GenericConverter; import org.springframework.format.Formatter; import org.springframework.format.FormatterRegistry; import org.springframework.http.CacheControl; -import org.springframework.http.server.reactive.HttpHandler; -import org.springframework.web.reactive.DispatcherHandler; import org.springframework.web.reactive.config.DelegatingWebFluxConfiguration; import org.springframework.web.reactive.config.EnableWebFlux; import org.springframework.web.reactive.config.ResourceChainRegistration; @@ -65,18 +60,18 @@ import org.springframework.web.reactive.resource.ResourceResolver; import org.springframework.web.reactive.resource.VersionResourceResolver; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.view.ViewResolver; -import org.springframework.web.server.adapter.WebHttpHandlerBuilder; /** * {@link EnableAutoConfiguration Auto-configuration} for {@link EnableWebFlux WebFlux}. * * @author Brian Clozel * @author Rob Winch + * @author Stephane Nicoll */ @Configuration @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) -@ConditionalOnClass({DispatcherHandler.class, HttpHandler.class}) -@ConditionalOnMissingBean({RouterFunction.class, HttpHandler.class}) +@ConditionalOnClass(WebFluxConfigurer.class) +@ConditionalOnMissingBean(RouterFunction.class) @AutoConfigureAfter(ReactiveWebServerAutoConfiguration.class) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) public class WebFluxAnnotationAutoConfiguration { @@ -183,24 +178,6 @@ public class WebFluxAnnotationAutoConfiguration { } } - @Configuration - @Import(WebFluxConfig.class) - public static class WebHttpHandlerConfiguration implements ApplicationContextAware { - - private ApplicationContext applicationContext; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { - this.applicationContext = applicationContext; - } - - @Bean - public HttpHandler httpHandler() { - return WebHttpHandlerBuilder.applicationContext(this.applicationContext).build(); - } - } - @Configuration @ConditionalOnEnabledResourceChain static class ResourceChainCustomizerConfiguration { diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 0bcb57b33bd..0a3781fe3d2 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -112,9 +112,9 @@ org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguratio org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\ org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\ org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\ +org.springframework.boot.autoconfigure.webflux.HttpHandlerAutoConfiguration,\ org.springframework.boot.autoconfigure.webflux.ReactiveWebServerAutoConfiguration,\ org.springframework.boot.autoconfigure.webflux.WebFluxAnnotationAutoConfiguration,\ -org.springframework.boot.autoconfigure.webflux.WebFluxFunctionalAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\ org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/WebFluxFunctionalAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/HttpHandlerAutoConfigurationTests.java similarity index 60% rename from spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/WebFluxFunctionalAutoConfigurationTests.java rename to spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/HttpHandlerAutoConfigurationTests.java index a9a69ddbdca..b6a4893c103 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/WebFluxFunctionalAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/HttpHandlerAutoConfigurationTests.java @@ -20,59 +20,82 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.springframework.boot.context.embedded.EmbeddedReactiveWebApplicationContext; -import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.context.GenericReactiveWebApplicationContext; import org.springframework.boot.test.util.EnvironmentTestUtils; -import org.springframework.context.ApplicationContextException; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import org.springframework.http.server.reactive.HttpHandler; import org.springframework.web.reactive.function.server.RequestPredicates; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebHandler; -import org.springframework.web.server.adapter.HttpWebHandlerAdapter; import org.springframework.web.server.handler.FilteringWebHandler; import org.springframework.web.server.handler.WebHandlerDecorator; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; +import static org.mockito.Mockito.mock; /** - * Tests for {@link WebFluxFunctionalAutoConfiguration}. + * Tests for {@link HttpHandlerAutoConfiguration}. * * @author Brian Clozel + * @author Stephane Nicoll */ -public class WebFluxFunctionalAutoConfigurationTests { +public class HttpHandlerAutoConfigurationTests { @Rule public ExpectedException thrown = ExpectedException.none(); - private EmbeddedReactiveWebApplicationContext context; + private GenericReactiveWebApplicationContext context; @Test - public void shouldNotProcessIfExistingHttpHandler() throws Exception { + public void shouldNotProcessIfExistingHttpHandler() { load(CustomHttpHandler.class); - assertThat(this.context.getBeansOfType(HttpWebHandlerAdapter.class).size()).isEqualTo(0); + assertThat(this.context.getBeansOfType(HttpHandler.class)).hasSize(1); + assertThat(this.context.getBean(HttpHandler.class)).isSameAs( + this.context.getBean("customHttpHandler")); } @Test - public void shouldFailIfNoHttpHandler() throws Exception { - this.thrown.expect(ApplicationContextException.class); - this.thrown.expectMessage("Unable to start ReactiveWebApplicationContext due to missing HttpHandler bean."); - load(BaseConfiguration.class); + public void shouldConfigureHttpHandlerAnnotation() { + load(WebFluxAnnotationAutoConfiguration.class); + assertThat(this.context.getBeansOfType(HttpHandler.class).size()).isEqualTo(1); } @Test - public void shouldConfigureHttpHandler() { + public void shouldConfigureHttpHandlerFunctional() { load(FunctionalConfig.class); assertThat(this.context.getBeansOfType(HttpHandler.class).size()).isEqualTo(1); } @Test - public void shouldConfigureWebFilters() { + public void shouldConfigureWebFiltersAnnotation() { + load(AnnotationConfigWithWebFilters.class); + + HttpHandler handler = this.context.getBean(HttpHandler.class); + assertThat(handler).isInstanceOf(WebHandler.class); + WebHandler webHandler = (WebHandler) handler; + while (webHandler instanceof WebHandlerDecorator) { + if (webHandler instanceof FilteringWebHandler) { + FilteringWebHandler filteringWebHandler = (FilteringWebHandler) webHandler; + assertThat(filteringWebHandler.getFilters()).containsExactly( + this.context.getBean("firstWebFilter", WebFilter.class), + this.context.getBean("aWebFilter", WebFilter.class), + this.context.getBean("lastWebFilter", WebFilter.class)); + return; + } + webHandler = ((WebHandlerDecorator) webHandler).getDelegate(); + } + fail("Did not find any FilteringWebHandler"); + } + + @Test + public void shouldConfigureWebFiltersFunctional() { load(FunctionalConfigWithWebFilters.class); assertThat(this.context.getBeansOfType(HttpHandler.class).size()).isEqualTo(1); HttpHandler handler = this.context.getBean(HttpHandler.class); @@ -92,24 +115,34 @@ public class WebFluxFunctionalAutoConfigurationTests { private void load(Class config, String... environment) { - this.context = new EmbeddedReactiveWebApplicationContext(); + this.context = new GenericReactiveWebApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, environment); - this.context.register(config); - if (!config.equals(BaseConfiguration.class)) { - this.context.register(BaseConfiguration.class); + if (this.context != null) { + this.context.register(config); } + this.context.register(HttpHandlerAutoConfiguration.class); this.context.refresh(); } - @Configuration - @Import({WebFluxFunctionalAutoConfiguration.class}) - @EnableConfigurationProperties(WebFluxProperties.class) - protected static class BaseConfiguration { + @Import(WebFluxAnnotationAutoConfiguration.class) + protected static class AnnotationConfigWithWebFilters { + + @Bean + public WebFilter aWebFilter() { + return mock(WebFilter.class); + } + + @Bean + @Order(Ordered.LOWEST_PRECEDENCE) + public WebFilter lastWebFilter() { + return mock(WebFilter.class); + } @Bean - public MockReactiveWebServerFactory mockReactiveWebServerFactory() { - return new MockReactiveWebServerFactory(); + @Order(Ordered.HIGHEST_PRECEDENCE) + public WebFilter firstWebFilter() { + return mock(WebFilter.class); } } @@ -140,7 +173,7 @@ public class WebFluxFunctionalAutoConfigurationTests { protected static class CustomHttpHandler { @Bean - public HttpHandler httpHandler() { + public HttpHandler customHttpHandler() { return (serverHttpRequest, serverHttpResponse) -> null; } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/WebFluxAnnotationAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/WebFluxAnnotationAutoConfigurationTests.java index 6c28cda98ff..60ca28f257d 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/WebFluxAnnotationAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/WebFluxAnnotationAutoConfigurationTests.java @@ -18,7 +18,7 @@ package org.springframework.boot.autoconfigure.webflux; import org.junit.Test; -import org.springframework.boot.context.embedded.EmbeddedReactiveWebApplicationContext; +import org.springframework.boot.context.GenericReactiveWebApplicationContext; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.context.annotation.Bean; @@ -41,14 +41,9 @@ import org.springframework.web.reactive.result.method.annotation.RequestMappingH import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.reactive.result.view.ViewResolutionResultHandler; import org.springframework.web.reactive.result.view.ViewResolver; -import org.springframework.web.server.WebFilter; -import org.springframework.web.server.WebHandler; import org.springframework.web.server.adapter.HttpWebHandlerAdapter; -import org.springframework.web.server.handler.FilteringWebHandler; -import org.springframework.web.server.handler.WebHandlerDecorator; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; import static org.mockito.Mockito.mock; /** @@ -58,78 +53,57 @@ import static org.mockito.Mockito.mock; */ public class WebFluxAnnotationAutoConfigurationTests { - private EmbeddedReactiveWebApplicationContext context; - - @Test - public void shouldNotProcessIfExistingHttpHandler() throws Exception { - load(CustomHttpHandler.class); - - assertThat(this.context.getBeansOfType(RequestMappingHandlerMapping.class).size()).isEqualTo(0); - assertThat(this.context.getBeansOfType(RequestMappingHandlerAdapter.class).size()).isEqualTo(0); - assertThat(this.context.getBeansOfType(HttpWebHandlerAdapter.class).size()).isEqualTo(0); - } - + private GenericReactiveWebApplicationContext context; @Test public void shouldNotProcessIfExistingWebReactiveConfiguration() throws Exception { load(WebFluxConfigurationSupport.class); - assertThat(this.context.getBeansOfType(RequestMappingHandlerMapping.class).size()).isEqualTo(1); - assertThat(this.context.getBeansOfType(RequestMappingHandlerAdapter.class).size()).isEqualTo(1); + assertThat(this.context.getBeansOfType(RequestMappingHandlerMapping.class) + .size()).isEqualTo(1); + assertThat(this.context.getBeansOfType(RequestMappingHandlerAdapter.class) + .size()).isEqualTo(1); } @Test public void shouldCreateDefaultBeans() throws Exception { - load(BaseConfiguration.class); + load(); - assertThat(this.context.getBeansOfType(RequestMappingHandlerMapping.class).size()).isEqualTo(1); - assertThat(this.context.getBeansOfType(RequestMappingHandlerAdapter.class).size()).isEqualTo(1); - assertThat(this.context.getBeansOfType(CompositeContentTypeResolver.class).size()).isEqualTo(1); - assertThat(this.context.getBean("resourceHandlerMapping", HandlerMapping.class)).isNotNull(); + assertThat(this.context.getBeansOfType(RequestMappingHandlerMapping.class) + .size()).isEqualTo(1); + assertThat(this.context.getBeansOfType(RequestMappingHandlerAdapter.class) + .size()).isEqualTo(1); + assertThat(this.context.getBeansOfType(CompositeContentTypeResolver.class) + .size()).isEqualTo(1); + assertThat(this.context.getBean("resourceHandlerMapping", HandlerMapping.class)) + .isNotNull(); } @Test public void shouldRegisterCustomHandlerMethodArgumentResolver() throws Exception { load(CustomArgumentResolvers.class); - RequestMappingHandlerAdapter adapter = this.context.getBean(RequestMappingHandlerAdapter.class); - assertThat(adapter.getArgumentResolvers()) - .contains(this.context.getBean("firstResolver", HandlerMethodArgumentResolver.class), - this.context.getBean("secondResolver", HandlerMethodArgumentResolver.class)); - } - - @Test - public void shouldRegisterCustomWebFilters() throws Exception { - load(CustomWebFilters.class); - - HttpHandler handler = this.context.getBean(HttpHandler.class); - assertThat(handler).isInstanceOf(WebHandler.class); - WebHandler webHandler = (WebHandler) handler; - while (webHandler instanceof WebHandlerDecorator) { - if (webHandler instanceof FilteringWebHandler) { - FilteringWebHandler filteringWebHandler = (FilteringWebHandler) webHandler; - assertThat(filteringWebHandler.getFilters()).containsExactly( - this.context.getBean("firstWebFilter", WebFilter.class), - this.context.getBean("aWebFilter", WebFilter.class), - this.context.getBean("lastWebFilter", WebFilter.class)); - return; - } - webHandler = ((WebHandlerDecorator) webHandler).getDelegate(); - } - fail("Did not find any FilteringWebHandler"); + RequestMappingHandlerAdapter adapter = this.context.getBean( + RequestMappingHandlerAdapter.class); + assertThat(adapter.getArgumentResolvers()).contains( + this.context.getBean("firstResolver", HandlerMethodArgumentResolver.class), + this.context.getBean("secondResolver", HandlerMethodArgumentResolver.class)); } @Test public void shouldRegisterResourceHandlerMapping() throws Exception { - load(BaseConfiguration.class); + load(); - SimpleUrlHandlerMapping hm = this.context.getBean("resourceHandlerMapping", SimpleUrlHandlerMapping.class); + SimpleUrlHandlerMapping hm = this.context.getBean("resourceHandlerMapping", + SimpleUrlHandlerMapping.class); assertThat(hm.getUrlMap().get("/**")).isInstanceOf(ResourceWebHandler.class); ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap().get("/**"); assertThat(staticHandler.getLocations()).hasSize(5); - assertThat(hm.getUrlMap().get("/webjars/**")).isInstanceOf(ResourceWebHandler.class); - ResourceWebHandler webjarsHandler = (ResourceWebHandler) hm.getUrlMap().get("/webjars/**"); + assertThat(hm.getUrlMap().get("/webjars/**")) + .isInstanceOf(ResourceWebHandler.class); + ResourceWebHandler webjarsHandler = (ResourceWebHandler) hm.getUrlMap() + .get("/webjars/**"); assertThat(webjarsHandler.getLocations()).hasSize(1); assertThat(webjarsHandler.getLocations().get(0)) .isEqualTo(new ClassPathResource("/META-INF/resources/webjars/")); @@ -137,23 +111,28 @@ public class WebFluxAnnotationAutoConfigurationTests { @Test public void shouldMapResourcesToCustomPath() throws Exception { - load(BaseConfiguration.class, "spring.webflux.static-path-pattern:/static/**"); - SimpleUrlHandlerMapping hm = this.context.getBean("resourceHandlerMapping", SimpleUrlHandlerMapping.class); - assertThat(hm.getUrlMap().get("/static/**")).isInstanceOf(ResourceWebHandler.class); - ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap().get("/static/**"); + load("spring.webflux.static-path-pattern:/static/**"); + SimpleUrlHandlerMapping hm = this.context.getBean("resourceHandlerMapping", + SimpleUrlHandlerMapping.class); + assertThat(hm.getUrlMap().get("/static/**")) + .isInstanceOf(ResourceWebHandler.class); + ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap() + .get("/static/**"); assertThat(staticHandler.getLocations()).hasSize(5); } @Test public void shouldNotMapResourcesWhenDisabled() throws Exception { - load(BaseConfiguration.class, "spring.resources.add-mappings:false"); - assertThat(this.context.getBean("resourceHandlerMapping")).isNotInstanceOf(SimpleUrlHandlerMapping.class); + load("spring.resources.add-mappings:false"); + assertThat(this.context.getBean("resourceHandlerMapping")) + .isNotInstanceOf(SimpleUrlHandlerMapping.class); } @Test public void resourceHandlerChainEnabled() throws Exception { - load(BaseConfiguration.class, "spring.resources.chain.enabled:true"); - SimpleUrlHandlerMapping hm = this.context.getBean("resourceHandlerMapping", SimpleUrlHandlerMapping.class); + load("spring.resources.chain.enabled:true"); + SimpleUrlHandlerMapping hm = this.context.getBean("resourceHandlerMapping", + SimpleUrlHandlerMapping.class); assertThat(hm.getUrlMap().get("/**")).isInstanceOf(ResourceWebHandler.class); ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap().get("/**"); assertThat(staticHandler.getResourceResolvers()).extractingResultOf("getClass") @@ -165,45 +144,28 @@ public class WebFluxAnnotationAutoConfigurationTests { @Test public void shouldRegisterViewResolvers() throws Exception { load(ViewResolvers.class); - ViewResolutionResultHandler resultHandler = this.context.getBean(ViewResolutionResultHandler.class); + ViewResolutionResultHandler resultHandler = this.context.getBean( + ViewResolutionResultHandler.class); assertThat(resultHandler.getViewResolvers()).containsExactly( this.context.getBean("aViewResolver", ViewResolver.class), this.context.getBean("anotherViewResolver", ViewResolver.class) ); } + private void load(String... environment) { + load(null, environment); + } + private void load(Class config, String... environment) { - this.context = new EmbeddedReactiveWebApplicationContext(); + this.context = new GenericReactiveWebApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, environment); - this.context.register(config); - if (!config.equals(BaseConfiguration.class)) { - this.context.register(BaseConfiguration.class); + if (config != null) { + this.context.register(config); } + this.context.register(BaseConfiguration.class); this.context.refresh(); } - - @Configuration - protected static class CustomWebFilters { - - @Bean - public WebFilter aWebFilter() { - return mock(WebFilter.class); - } - - @Bean - @Order(Ordered.LOWEST_PRECEDENCE) - public WebFilter lastWebFilter() { - return mock(WebFilter.class); - } - - @Bean - @Order(Ordered.HIGHEST_PRECEDENCE) - public WebFilter firstWebFilter() { - return mock(WebFilter.class); - } - } - @Configuration protected static class CustomArgumentResolvers {