Browse Source

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
pull/8252/merge
Stephane Nicoll 9 years ago
parent
commit
deaa6089b0
  1. 52
      spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/HttpHandlerAutoConfiguration.java
  2. 29
      spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/WebFluxAnnotationAutoConfiguration.java
  3. 2
      spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
  4. 85
      spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/HttpHandlerAutoConfigurationTests.java
  5. 138
      spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/WebFluxAnnotationAutoConfigurationTests.java

52
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/WebFluxFunctionalAutoConfiguration.java → spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webflux/HttpHandlerAutoConfiguration.java

@ -16,7 +16,6 @@
package org.springframework.boot.autoconfigure.webflux; package org.springframework.boot.autoconfigure.webflux;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.ObjectProvider; 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.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
@ -45,21 +45,40 @@ import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
import org.springframework.web.server.session.WebSessionManager; 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 Brian Clozel
* @author Stephane Nicoll
*/ */
@Configuration @Configuration
@ConditionalOnClass({DispatcherHandler.class, HttpHandler.class}) @ConditionalOnClass({ DispatcherHandler.class, HttpHandler.class })
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
@ConditionalOnBean(RouterFunction.class)
@ConditionalOnMissingBean(HttpHandler.class) @ConditionalOnMissingBean(HttpHandler.class)
@AutoConfigureAfter({ReactiveWebServerAutoConfiguration.class}) @AutoConfigureAfter({ WebFluxAnnotationAutoConfiguration.class })
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
public class WebFluxFunctionalAutoConfiguration { public class HttpHandlerAutoConfiguration {
@Configuration @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<WebFilter> webFilters; private final List<WebFilter> webFilters;
@ -71,7 +90,7 @@ public class WebFluxFunctionalAutoConfiguration {
private final List<ViewResolver> viewResolvers; private final List<ViewResolver> viewResolvers;
public WebFluxFunctionalConfig(ObjectProvider<List<WebFilter>> webFilters, public FunctionalConfig(ObjectProvider<List<WebFilter>> webFilters,
ObjectProvider<WebSessionManager> webSessionManager, ObjectProvider<WebSessionManager> webSessionManager,
ObjectProvider<List<HttpMessageReader>> messageReaders, ObjectProvider<List<HttpMessageReader>> messageReaders,
ObjectProvider<List<HttpMessageWriter>> messageWriters, ObjectProvider<List<HttpMessageWriter>> messageWriters,
@ -88,24 +107,27 @@ public class WebFluxFunctionalAutoConfiguration {
@Bean @Bean
public HttpHandler httpHandler(List<RouterFunction> routerFunctions) { public HttpHandler httpHandler(List<RouterFunction> routerFunctions) {
Collections.sort(routerFunctions, new AnnotationAwareOrderComparator()); routerFunctions.sort(new AnnotationAwareOrderComparator());
RouterFunction routerFunction = routerFunctions.stream().reduce(RouterFunction::and).get(); RouterFunction routerFunction = routerFunctions.stream()
.reduce(RouterFunction::and).get();
HandlerStrategies.Builder strategiesBuilder = HandlerStrategies.builder(); HandlerStrategies.Builder strategiesBuilder = HandlerStrategies.builder();
if (this.messageReaders != null) { if (this.messageReaders != null) {
this.messageReaders.forEach(reader -> strategiesBuilder.messageReader(reader)); this.messageReaders.forEach(strategiesBuilder::messageReader);
} }
if (this.messageWriters != null) { if (this.messageWriters != null) {
this.messageWriters.forEach(writer -> strategiesBuilder.messageWriter(writer)); this.messageWriters.forEach(strategiesBuilder::messageWriter);
} }
if (this.viewResolvers != null) { 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 WebHttpHandlerBuilder builder = WebHttpHandlerBuilder
.webHandler(webHandler) .webHandler(webHandler)
.sessionManager(this.webSessionManager); .sessionManager(this.webSessionManager);
if (this.webFilters != null) { 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(); return builder.build();
} }

29
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.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired; 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.ConditionalOnEnabledResourceChain;
import org.springframework.boot.autoconfigure.web.ResourceProperties; import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties; 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.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; 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.Formatter;
import org.springframework.format.FormatterRegistry; import org.springframework.format.FormatterRegistry;
import org.springframework.http.CacheControl; 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.DelegatingWebFluxConfiguration;
import org.springframework.web.reactive.config.EnableWebFlux; import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.config.ResourceChainRegistration; 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.resource.VersionResourceResolver;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.reactive.result.view.ViewResolver; import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
/** /**
* {@link EnableAutoConfiguration Auto-configuration} for {@link EnableWebFlux WebFlux}. * {@link EnableAutoConfiguration Auto-configuration} for {@link EnableWebFlux WebFlux}.
* *
* @author Brian Clozel * @author Brian Clozel
* @author Rob Winch * @author Rob Winch
* @author Stephane Nicoll
*/ */
@Configuration @Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
@ConditionalOnClass({DispatcherHandler.class, HttpHandler.class}) @ConditionalOnClass(WebFluxConfigurer.class)
@ConditionalOnMissingBean({RouterFunction.class, HttpHandler.class}) @ConditionalOnMissingBean(RouterFunction.class)
@AutoConfigureAfter(ReactiveWebServerAutoConfiguration.class) @AutoConfigureAfter(ReactiveWebServerAutoConfiguration.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
public class WebFluxAnnotationAutoConfiguration { 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 @Configuration
@ConditionalOnEnabledResourceChain @ConditionalOnEnabledResourceChain
static class ResourceChainCustomizerConfiguration { static class ResourceChainCustomizerConfiguration {

2
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.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\ org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.webflux.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.webflux.ReactiveWebServerAutoConfiguration,\ org.springframework.boot.autoconfigure.webflux.ReactiveWebServerAutoConfiguration,\
org.springframework.boot.autoconfigure.webflux.WebFluxAnnotationAutoConfiguration,\ org.springframework.boot.autoconfigure.webflux.WebFluxAnnotationAutoConfiguration,\
org.springframework.boot.autoconfigure.webflux.WebFluxFunctionalAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration

85
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webflux/WebFluxFunctionalAutoConfigurationTests.java → 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.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
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.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; 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.http.server.reactive.HttpHandler;
import org.springframework.web.reactive.function.server.RequestPredicates; import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebHandler; 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.FilteringWebHandler;
import org.springframework.web.server.handler.WebHandlerDecorator; import org.springframework.web.server.handler.WebHandlerDecorator;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail; 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 Brian Clozel
* @author Stephane Nicoll
*/ */
public class WebFluxFunctionalAutoConfigurationTests { public class HttpHandlerAutoConfigurationTests {
@Rule @Rule
public ExpectedException thrown = ExpectedException.none(); public ExpectedException thrown = ExpectedException.none();
private EmbeddedReactiveWebApplicationContext context; private GenericReactiveWebApplicationContext context;
@Test @Test
public void shouldNotProcessIfExistingHttpHandler() throws Exception { public void shouldNotProcessIfExistingHttpHandler() {
load(CustomHttpHandler.class); 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 @Test
public void shouldFailIfNoHttpHandler() throws Exception { public void shouldConfigureHttpHandlerAnnotation() {
this.thrown.expect(ApplicationContextException.class); load(WebFluxAnnotationAutoConfiguration.class);
this.thrown.expectMessage("Unable to start ReactiveWebApplicationContext due to missing HttpHandler bean."); assertThat(this.context.getBeansOfType(HttpHandler.class).size()).isEqualTo(1);
load(BaseConfiguration.class);
} }
@Test @Test
public void shouldConfigureHttpHandler() { public void shouldConfigureHttpHandlerFunctional() {
load(FunctionalConfig.class); load(FunctionalConfig.class);
assertThat(this.context.getBeansOfType(HttpHandler.class).size()).isEqualTo(1); assertThat(this.context.getBeansOfType(HttpHandler.class).size()).isEqualTo(1);
} }
@Test @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); load(FunctionalConfigWithWebFilters.class);
assertThat(this.context.getBeansOfType(HttpHandler.class).size()).isEqualTo(1); assertThat(this.context.getBeansOfType(HttpHandler.class).size()).isEqualTo(1);
HttpHandler handler = this.context.getBean(HttpHandler.class); HttpHandler handler = this.context.getBean(HttpHandler.class);
@ -92,24 +115,34 @@ public class WebFluxFunctionalAutoConfigurationTests {
private void load(Class<?> config, String... environment) { private void load(Class<?> config, String... environment) {
this.context = new EmbeddedReactiveWebApplicationContext(); this.context = new GenericReactiveWebApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context, environment); EnvironmentTestUtils.addEnvironment(this.context, environment);
this.context.register(config); if (this.context != null) {
if (!config.equals(BaseConfiguration.class)) { this.context.register(config);
this.context.register(BaseConfiguration.class);
} }
this.context.register(HttpHandlerAutoConfiguration.class);
this.context.refresh(); this.context.refresh();
} }
@Configuration @Configuration
@Import({WebFluxFunctionalAutoConfiguration.class}) @Import(WebFluxAnnotationAutoConfiguration.class)
@EnableConfigurationProperties(WebFluxProperties.class) protected static class AnnotationConfigWithWebFilters {
protected static class BaseConfiguration {
@Bean
public WebFilter aWebFilter() {
return mock(WebFilter.class);
}
@Bean
@Order(Ordered.LOWEST_PRECEDENCE)
public WebFilter lastWebFilter() {
return mock(WebFilter.class);
}
@Bean @Bean
public MockReactiveWebServerFactory mockReactiveWebServerFactory() { @Order(Ordered.HIGHEST_PRECEDENCE)
return new MockReactiveWebServerFactory(); public WebFilter firstWebFilter() {
return mock(WebFilter.class);
} }
} }
@ -140,7 +173,7 @@ public class WebFluxFunctionalAutoConfigurationTests {
protected static class CustomHttpHandler { protected static class CustomHttpHandler {
@Bean @Bean
public HttpHandler httpHandler() { public HttpHandler customHttpHandler() {
return (serverHttpRequest, serverHttpResponse) -> null; return (serverHttpRequest, serverHttpResponse) -> null;
} }

138
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.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.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.annotation.Bean; 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.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.reactive.result.view.ViewResolutionResultHandler; import org.springframework.web.reactive.result.view.ViewResolutionResultHandler;
import org.springframework.web.reactive.result.view.ViewResolver; 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.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.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
/** /**
@ -58,78 +53,57 @@ import static org.mockito.Mockito.mock;
*/ */
public class WebFluxAnnotationAutoConfigurationTests { public class WebFluxAnnotationAutoConfigurationTests {
private EmbeddedReactiveWebApplicationContext context; private GenericReactiveWebApplicationContext 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);
}
@Test @Test
public void shouldNotProcessIfExistingWebReactiveConfiguration() throws Exception { public void shouldNotProcessIfExistingWebReactiveConfiguration() throws Exception {
load(WebFluxConfigurationSupport.class); load(WebFluxConfigurationSupport.class);
assertThat(this.context.getBeansOfType(RequestMappingHandlerMapping.class).size()).isEqualTo(1); assertThat(this.context.getBeansOfType(RequestMappingHandlerMapping.class)
assertThat(this.context.getBeansOfType(RequestMappingHandlerAdapter.class).size()).isEqualTo(1); .size()).isEqualTo(1);
assertThat(this.context.getBeansOfType(RequestMappingHandlerAdapter.class)
.size()).isEqualTo(1);
} }
@Test @Test
public void shouldCreateDefaultBeans() throws Exception { public void shouldCreateDefaultBeans() throws Exception {
load(BaseConfiguration.class); load();
assertThat(this.context.getBeansOfType(RequestMappingHandlerMapping.class).size()).isEqualTo(1); assertThat(this.context.getBeansOfType(RequestMappingHandlerMapping.class)
assertThat(this.context.getBeansOfType(RequestMappingHandlerAdapter.class).size()).isEqualTo(1); .size()).isEqualTo(1);
assertThat(this.context.getBeansOfType(CompositeContentTypeResolver.class).size()).isEqualTo(1); assertThat(this.context.getBeansOfType(RequestMappingHandlerAdapter.class)
assertThat(this.context.getBean("resourceHandlerMapping", HandlerMapping.class)).isNotNull(); .size()).isEqualTo(1);
assertThat(this.context.getBeansOfType(CompositeContentTypeResolver.class)
.size()).isEqualTo(1);
assertThat(this.context.getBean("resourceHandlerMapping", HandlerMapping.class))
.isNotNull();
} }
@Test @Test
public void shouldRegisterCustomHandlerMethodArgumentResolver() throws Exception { public void shouldRegisterCustomHandlerMethodArgumentResolver() throws Exception {
load(CustomArgumentResolvers.class); load(CustomArgumentResolvers.class);
RequestMappingHandlerAdapter adapter = this.context.getBean(RequestMappingHandlerAdapter.class); RequestMappingHandlerAdapter adapter = this.context.getBean(
assertThat(adapter.getArgumentResolvers()) RequestMappingHandlerAdapter.class);
.contains(this.context.getBean("firstResolver", HandlerMethodArgumentResolver.class), assertThat(adapter.getArgumentResolvers()).contains(
this.context.getBean("secondResolver", HandlerMethodArgumentResolver.class)); 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");
} }
@Test @Test
public void shouldRegisterResourceHandlerMapping() throws Exception { 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); assertThat(hm.getUrlMap().get("/**")).isInstanceOf(ResourceWebHandler.class);
ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap().get("/**"); ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap().get("/**");
assertThat(staticHandler.getLocations()).hasSize(5); assertThat(staticHandler.getLocations()).hasSize(5);
assertThat(hm.getUrlMap().get("/webjars/**")).isInstanceOf(ResourceWebHandler.class); assertThat(hm.getUrlMap().get("/webjars/**"))
ResourceWebHandler webjarsHandler = (ResourceWebHandler) hm.getUrlMap().get("/webjars/**"); .isInstanceOf(ResourceWebHandler.class);
ResourceWebHandler webjarsHandler = (ResourceWebHandler) hm.getUrlMap()
.get("/webjars/**");
assertThat(webjarsHandler.getLocations()).hasSize(1); assertThat(webjarsHandler.getLocations()).hasSize(1);
assertThat(webjarsHandler.getLocations().get(0)) assertThat(webjarsHandler.getLocations().get(0))
.isEqualTo(new ClassPathResource("/META-INF/resources/webjars/")); .isEqualTo(new ClassPathResource("/META-INF/resources/webjars/"));
@ -137,23 +111,28 @@ public class WebFluxAnnotationAutoConfigurationTests {
@Test @Test
public void shouldMapResourcesToCustomPath() throws Exception { public void shouldMapResourcesToCustomPath() throws Exception {
load(BaseConfiguration.class, "spring.webflux.static-path-pattern:/static/**"); load("spring.webflux.static-path-pattern:/static/**");
SimpleUrlHandlerMapping hm = this.context.getBean("resourceHandlerMapping", SimpleUrlHandlerMapping.class); SimpleUrlHandlerMapping hm = this.context.getBean("resourceHandlerMapping",
assertThat(hm.getUrlMap().get("/static/**")).isInstanceOf(ResourceWebHandler.class); SimpleUrlHandlerMapping.class);
ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap().get("/static/**"); assertThat(hm.getUrlMap().get("/static/**"))
.isInstanceOf(ResourceWebHandler.class);
ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap()
.get("/static/**");
assertThat(staticHandler.getLocations()).hasSize(5); assertThat(staticHandler.getLocations()).hasSize(5);
} }
@Test @Test
public void shouldNotMapResourcesWhenDisabled() throws Exception { public void shouldNotMapResourcesWhenDisabled() throws Exception {
load(BaseConfiguration.class, "spring.resources.add-mappings:false"); load("spring.resources.add-mappings:false");
assertThat(this.context.getBean("resourceHandlerMapping")).isNotInstanceOf(SimpleUrlHandlerMapping.class); assertThat(this.context.getBean("resourceHandlerMapping"))
.isNotInstanceOf(SimpleUrlHandlerMapping.class);
} }
@Test @Test
public void resourceHandlerChainEnabled() throws Exception { public void resourceHandlerChainEnabled() throws Exception {
load(BaseConfiguration.class, "spring.resources.chain.enabled:true"); load("spring.resources.chain.enabled:true");
SimpleUrlHandlerMapping hm = this.context.getBean("resourceHandlerMapping", SimpleUrlHandlerMapping.class); SimpleUrlHandlerMapping hm = this.context.getBean("resourceHandlerMapping",
SimpleUrlHandlerMapping.class);
assertThat(hm.getUrlMap().get("/**")).isInstanceOf(ResourceWebHandler.class); assertThat(hm.getUrlMap().get("/**")).isInstanceOf(ResourceWebHandler.class);
ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap().get("/**"); ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap().get("/**");
assertThat(staticHandler.getResourceResolvers()).extractingResultOf("getClass") assertThat(staticHandler.getResourceResolvers()).extractingResultOf("getClass")
@ -165,45 +144,28 @@ public class WebFluxAnnotationAutoConfigurationTests {
@Test @Test
public void shouldRegisterViewResolvers() throws Exception { public void shouldRegisterViewResolvers() throws Exception {
load(ViewResolvers.class); load(ViewResolvers.class);
ViewResolutionResultHandler resultHandler = this.context.getBean(ViewResolutionResultHandler.class); ViewResolutionResultHandler resultHandler = this.context.getBean(
ViewResolutionResultHandler.class);
assertThat(resultHandler.getViewResolvers()).containsExactly( assertThat(resultHandler.getViewResolvers()).containsExactly(
this.context.getBean("aViewResolver", ViewResolver.class), this.context.getBean("aViewResolver", ViewResolver.class),
this.context.getBean("anotherViewResolver", ViewResolver.class) this.context.getBean("anotherViewResolver", ViewResolver.class)
); );
} }
private void load(String... environment) {
load(null, environment);
}
private void load(Class<?> config, String... environment) { private void load(Class<?> config, String... environment) {
this.context = new EmbeddedReactiveWebApplicationContext(); this.context = new GenericReactiveWebApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context, environment); EnvironmentTestUtils.addEnvironment(this.context, environment);
this.context.register(config); if (config != null) {
if (!config.equals(BaseConfiguration.class)) { this.context.register(config);
this.context.register(BaseConfiguration.class);
} }
this.context.register(BaseConfiguration.class);
this.context.refresh(); 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 @Configuration
protected static class CustomArgumentResolvers { protected static class CustomArgumentResolvers {

Loading…
Cancel
Save