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
This commit is contained in:
@@ -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<WebFilter> webFilters;
|
||||
|
||||
@@ -71,7 +90,7 @@ public class WebFluxFunctionalAutoConfiguration {
|
||||
|
||||
private final List<ViewResolver> viewResolvers;
|
||||
|
||||
public WebFluxFunctionalConfig(ObjectProvider<List<WebFilter>> webFilters,
|
||||
public FunctionalConfig(ObjectProvider<List<WebFilter>> webFilters,
|
||||
ObjectProvider<WebSessionManager> webSessionManager,
|
||||
ObjectProvider<List<HttpMessageReader>> messageReaders,
|
||||
ObjectProvider<List<HttpMessageWriter>> messageWriters,
|
||||
@@ -88,24 +107,27 @@ public class WebFluxFunctionalAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public HttpHandler httpHandler(List<RouterFunction> 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();
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 MockReactiveWebServerFactory mockReactiveWebServerFactory() {
|
||||
return new MockReactiveWebServerFactory();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +173,7 @@ public class WebFluxFunctionalAutoConfigurationTests {
|
||||
protected static class CustomHttpHandler {
|
||||
|
||||
@Bean
|
||||
public HttpHandler httpHandler() {
|
||||
public HttpHandler customHttpHandler() {
|
||||
return (serverHttpRequest, serverHttpResponse) -> null;
|
||||
}
|
||||
|
||||
@@ -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,43 +144,26 @@ 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(Class<?> config, String... environment) {
|
||||
this.context = new EmbeddedReactiveWebApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(this.context, environment);
|
||||
this.context.register(config);
|
||||
if (!config.equals(BaseConfiguration.class)) {
|
||||
this.context.register(BaseConfiguration.class);
|
||||
}
|
||||
this.context.refresh();
|
||||
private void load(String... environment) {
|
||||
load(null, environment);
|
||||
}
|
||||
|
||||
|
||||
@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);
|
||||
private void load(Class<?> config, String... environment) {
|
||||
this.context = new GenericReactiveWebApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(this.context, environment);
|
||||
if (config != null) {
|
||||
this.context.register(config);
|
||||
}
|
||||
this.context.register(BaseConfiguration.class);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
Reference in New Issue
Block a user