diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfiguration.java index 43dc1a73b04..9cdbc9f6339 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfiguration.java @@ -16,13 +16,9 @@ package org.springframework.boot.autoconfigure.web.reactive; -import java.util.List; - -import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -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; @@ -30,17 +26,9 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.http.server.reactive.HttpHandler; import org.springframework.web.reactive.DispatcherHandler; -import org.springframework.web.reactive.function.server.HandlerStrategies; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.RouterFunctions; -import org.springframework.web.reactive.result.view.ViewResolver; -import org.springframework.web.server.WebFilter; -import org.springframework.web.server.adapter.HttpWebHandlerAdapter; import org.springframework.web.server.adapter.WebHttpHandlerBuilder; -import org.springframework.web.server.session.WebSessionManager; /** * {@link EnableAutoConfiguration Auto-configuration} for {@link HttpHandler}. @@ -58,7 +46,6 @@ import org.springframework.web.server.session.WebSessionManager; public class HttpHandlerAutoConfiguration { @Configuration - @ConditionalOnMissingBean(RouterFunction.class) public static class AnnotationConfig { private ApplicationContext applicationContext; @@ -69,58 +56,7 @@ public class HttpHandlerAutoConfiguration { @Bean public HttpHandler httpHandler() { - return WebHttpHandlerBuilder.applicationContext(this.applicationContext) - .build(); - } - - } - - @Configuration - @ConditionalOnBean(RouterFunction.class) - public static class FunctionalConfig { - - private final List webFilters; - - private final WebSessionManager webSessionManager; - - private HandlerStrategies.Builder handlerStrategiesBuilder; - - private final List viewResolvers; - - public FunctionalConfig(ObjectProvider> webFilters, - ObjectProvider webSessionManager, - ObjectProvider handlerStrategiesBuilder, - ObjectProvider> viewResolvers) { - this.webFilters = webFilters.getIfAvailable(); - if (this.webFilters != null) { - AnnotationAwareOrderComparator.sort(this.webFilters); - } - this.webSessionManager = webSessionManager.getIfAvailable(); - this.handlerStrategiesBuilder = handlerStrategiesBuilder.getIfAvailable(); - this.viewResolvers = viewResolvers.getIfAvailable(); - } - - @Bean - public HttpHandler httpHandler(List> routerFunctions) { - routerFunctions.sort(new AnnotationAwareOrderComparator()); - RouterFunction routerFunction = routerFunctions.stream() - .reduce(RouterFunction::andOther).get(); - if (this.handlerStrategiesBuilder == null) { - this.handlerStrategiesBuilder = HandlerStrategies.builder(); - } - if (this.webFilters != null) { - this.webFilters.forEach(this.handlerStrategiesBuilder::webFilter); - } - if (this.viewResolvers != null) { - this.viewResolvers.forEach(this.handlerStrategiesBuilder::viewResolver); - } - HttpHandler httpHandler = RouterFunctions.toHttpHandler(routerFunction, - this.handlerStrategiesBuilder.build()); - if (this.webSessionManager != null) { - ((HttpWebHandlerAdapter) httpHandler) - .setSessionManager(this.webSessionManager); - } - return httpHandler; + return WebHttpHandlerBuilder.applicationContext(this.applicationContext).build(); } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java index 3204f1c060f..6e35f2527c2 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java @@ -56,7 +56,6 @@ import org.springframework.web.reactive.config.ResourceHandlerRegistry; import org.springframework.web.reactive.config.ViewResolverRegistry; import org.springframework.web.reactive.config.WebFluxConfigurationSupport; import org.springframework.web.reactive.config.WebFluxConfigurer; -import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.resource.AppCacheManifestTransformer; import org.springframework.web.reactive.resource.GzipResourceResolver; import org.springframework.web.reactive.resource.ResourceResolver; @@ -79,7 +78,7 @@ import org.springframework.web.reactive.result.view.ViewResolver; @Configuration @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) @ConditionalOnClass(WebFluxConfigurer.class) -@ConditionalOnMissingBean({ WebFluxConfigurationSupport.class, RouterFunction.class }) +@ConditionalOnMissingBean({ WebFluxConfigurationSupport.class }) @AutoConfigureAfter(ReactiveWebServerAutoConfiguration.class) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) public class WebFluxAutoConfiguration { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfigurationTests.java index db4defa45b0..36f51b5a94a 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfigurationTests.java @@ -24,22 +24,13 @@ import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext; 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.reactive.function.server.ServerResponse; -import org.springframework.web.server.WebFilter; -import org.springframework.web.server.WebHandler; -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 HttpHandlerAutoConfiguration}. @@ -68,52 +59,6 @@ public class HttpHandlerAutoConfigurationTests { assertThat(this.context.getBeansOfType(HttpHandler.class).size()).isEqualTo(1); } - @Test - public void shouldConfigureHttpHandlerFunctional() { - load(FunctionalConfig.class); - assertThat(this.context.getBeansOfType(HttpHandler.class).size()).isEqualTo(1); - } - - @Test - 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); - 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("customWebFilter", WebFilter.class)); - return; - } - webHandler = ((WebHandlerDecorator) webHandler).getDelegate(); - } - fail("Did not find any FilteringWebHandler"); - } - private void load(Class config, String... environment) { this.context = new GenericReactiveWebApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, environment); @@ -124,55 +69,6 @@ public class HttpHandlerAutoConfigurationTests { this.context.refresh(); } - @Configuration - @Import(WebFluxAutoConfiguration.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 - @Order(Ordered.HIGHEST_PRECEDENCE) - public WebFilter firstWebFilter() { - return mock(WebFilter.class); - } - } - - @Configuration - protected static class FunctionalConfig { - - @Bean - public RouterFunction routerFunction() { - return RouterFunctions.route(RequestPredicates.GET("/test"), - (serverRequest) -> null); - } - - } - - @Configuration - protected static class FunctionalConfigWithWebFilters { - - @Bean - public RouterFunction routerFunction() { - return RouterFunctions.route(RequestPredicates.GET("/test"), - (serverRequest) -> null); - } - - @Bean - public WebFilter customWebFilter() { - return (serverWebExchange, webFilterChain) -> null; - } - - } - @Configuration protected static class CustomHttpHandler { diff --git a/spring-boot-samples/spring-boot-sample-webflux/src/main/java/sample/webflux/EchoHandler.java b/spring-boot-samples/spring-boot-sample-webflux/src/main/java/sample/webflux/EchoHandler.java new file mode 100644 index 00000000000..b7ca7e77cd0 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-webflux/src/main/java/sample/webflux/EchoHandler.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.webflux; + +import reactor.core.publisher.Mono; + +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class EchoHandler { + + public Mono echo(ServerRequest request) { + return ServerResponse.ok().body(request.bodyToMono(String.class), String.class); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-webflux/src/main/java/sample/webflux/SampleWebFluxApplication.java b/spring-boot-samples/spring-boot-sample-webflux/src/main/java/sample/webflux/SampleWebFluxApplication.java index 680ea7c5c08..da39d6d3b86 100644 --- a/spring-boot-samples/spring-boot-sample-webflux/src/main/java/sample/webflux/SampleWebFluxApplication.java +++ b/spring-boot-samples/spring-boot-sample-webflux/src/main/java/sample/webflux/SampleWebFluxApplication.java @@ -18,6 +18,12 @@ package sample.webflux; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.ServerResponse; + +import static org.springframework.web.reactive.function.server.RequestPredicates.POST; +import static org.springframework.web.reactive.function.server.RouterFunctions.route; @SpringBootApplication public class SampleWebFluxApplication { @@ -26,4 +32,9 @@ public class SampleWebFluxApplication { SpringApplication.run(SampleWebFluxApplication.class); } + @Bean + public RouterFunction monoRouterFunction(EchoHandler echoHandler) { + return route(POST("/echo"), echoHandler::echo); + } + } diff --git a/spring-boot-samples/spring-boot-sample-webflux/src/test/java/sample/webflux/SampleWebFluxApplicationTests.java b/spring-boot-samples/spring-boot-sample-webflux/src/test/java/sample/webflux/SampleWebFluxApplicationTests.java index 19478faacc9..f59f8a5913a 100644 --- a/spring-boot-samples/spring-boot-sample-webflux/src/test/java/sample/webflux/SampleWebFluxApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-webflux/src/test/java/sample/webflux/SampleWebFluxApplicationTests.java @@ -18,6 +18,7 @@ package sample.webflux; import org.junit.Test; import org.junit.runner.RunWith; +import reactor.core.publisher.Mono; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -44,4 +45,14 @@ public class SampleWebFluxApplicationTests { .expectBody(String.class).isEqualTo("Hello World"); } + @Test + public void testEcho() throws Exception { + this.webClient.post().uri("/echo") + .contentType(MediaType.TEXT_PLAIN) + .accept(MediaType.TEXT_PLAIN) + .body(Mono.just("Hello WebFlux!"), String.class) + .exchange() + .expectBody(String.class).isEqualTo("Hello WebFlux!"); + } + }