Add WebFluxRegistrations for custom WebFlux beans
This commit adds a new `WebFluxRegistrations` interface that allows developers to register custom instances of key WebFlux infrastructure components, such as `RequestMappingHandlerMapping` and `RequestMappingHandlerAdapter`. Closes gh-13997
This commit is contained in:
parent
ba2f2a3727
commit
1c224e5fbb
|
|
@ -71,6 +71,8 @@ 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.method.annotation.ArgumentResolverConfigurer;
|
import org.springframework.web.reactive.result.method.annotation.ArgumentResolverConfigurer;
|
||||||
|
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
|
||||||
|
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
|
||||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -226,8 +228,12 @@ public class WebFluxAutoConfiguration {
|
||||||
|
|
||||||
private final WebFluxProperties webFluxProperties;
|
private final WebFluxProperties webFluxProperties;
|
||||||
|
|
||||||
public EnableWebFluxConfiguration(WebFluxProperties webFluxProperties) {
|
private final WebFluxRegistrations webFluxRegistrations;
|
||||||
|
|
||||||
|
public EnableWebFluxConfiguration(WebFluxProperties webFluxProperties,
|
||||||
|
ObjectProvider<WebFluxRegistrations> webFluxRegistrations) {
|
||||||
this.webFluxProperties = webFluxProperties;
|
this.webFluxProperties = webFluxProperties;
|
||||||
|
this.webFluxRegistrations = webFluxRegistrations.getIfUnique();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
@ -249,6 +255,24 @@ public class WebFluxAutoConfiguration {
|
||||||
return ValidatorAdapter.get(getApplicationContext(), getValidator());
|
return ValidatorAdapter.get(getApplicationContext(), getValidator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {
|
||||||
|
if (this.webFluxRegistrations != null && this.webFluxRegistrations
|
||||||
|
.getRequestMappingHandlerAdapter() != null) {
|
||||||
|
return this.webFluxRegistrations.getRequestMappingHandlerAdapter();
|
||||||
|
}
|
||||||
|
return super.createRequestMappingHandlerAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
|
||||||
|
if (this.webFluxRegistrations != null && this.webFluxRegistrations
|
||||||
|
.getRequestMappingHandlerMapping() != null) {
|
||||||
|
return this.webFluxRegistrations.getRequestMappingHandlerMapping();
|
||||||
|
}
|
||||||
|
return super.createRequestMappingHandlerMapping();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2018 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 org.springframework.boot.autoconfigure.web.reactive;
|
||||||
|
|
||||||
|
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
|
||||||
|
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to register key components of the {@link WebFluxAutoConfiguration} in place
|
||||||
|
* of the default ones provided by Spring WebFlux.
|
||||||
|
* <p>
|
||||||
|
* All custom instances are later processed by Boot and Spring WebFlux configurations. A
|
||||||
|
* single instance of this component should be registered, otherwise making it impossible
|
||||||
|
* to choose from redundant WebFlux components.
|
||||||
|
*
|
||||||
|
* @author Artsiom Yudovin
|
||||||
|
* @since 2.1.0
|
||||||
|
* @see org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration.EnableWebFluxConfiguration
|
||||||
|
*/
|
||||||
|
public interface WebFluxRegistrations {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the custom {@link RequestMappingHandlerMapping} that should be used and
|
||||||
|
* processed by the WebFlux configuration.
|
||||||
|
* @return the custom {@link RequestMappingHandlerMapping} instance
|
||||||
|
*/
|
||||||
|
default RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the custom {@link RequestMappingHandlerAdapter} that should be used and
|
||||||
|
* processed by the WebFlux configuration.
|
||||||
|
* @return the custom {@link RequestMappingHandlerAdapter} instance
|
||||||
|
*/
|
||||||
|
default RequestMappingHandlerAdapter getRequestMappingHandlerAdapter() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -33,6 +33,7 @@ import org.springframework.boot.web.codec.CodecCustomizer;
|
||||||
import org.springframework.boot.web.reactive.filter.OrderedHiddenHttpMethodFilter;
|
import org.springframework.boot.web.reactive.filter.OrderedHiddenHttpMethodFilter;
|
||||||
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.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
|
@ -370,6 +371,33 @@ public class WebFluxAutoConfigurationTests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void customRequestMappingHandlerMapping() {
|
||||||
|
this.contextRunner.withUserConfiguration(CustomRequestMappingHandlerMapping.class)
|
||||||
|
.run((context) -> assertThat(context)
|
||||||
|
.getBean(RequestMappingHandlerMapping.class)
|
||||||
|
.isInstanceOf(MyRequestMappingHandlerMapping.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void customRequestMappingHandlerAdapter() {
|
||||||
|
this.contextRunner.withUserConfiguration(CustomRequestMappingHandlerAdapter.class)
|
||||||
|
.run((context) -> assertThat(context)
|
||||||
|
.getBean(RequestMappingHandlerAdapter.class)
|
||||||
|
.isInstanceOf(MyRequestMappingHandlerAdapter.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void multipleWebFluxRegistrations() {
|
||||||
|
this.contextRunner.withUserConfiguration(MultipleWebFluxRegistrations.class)
|
||||||
|
.run((context) -> {
|
||||||
|
assertThat(context.getBean(RequestMappingHandlerMapping.class))
|
||||||
|
.isNotInstanceOf(MyRequestMappingHandlerMapping.class);
|
||||||
|
assertThat(context.getBean(RequestMappingHandlerAdapter.class))
|
||||||
|
.isNotInstanceOf(MyRequestMappingHandlerAdapter.class);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
protected static class CustomArgumentResolvers {
|
protected static class CustomArgumentResolvers {
|
||||||
|
|
||||||
|
|
@ -485,4 +513,55 @@ public class WebFluxAutoConfigurationTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class CustomRequestMappingHandlerAdapter {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public WebFluxRegistrations webMvcRegistrationsHandlerAdapter() {
|
||||||
|
return new WebFluxRegistrations() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RequestMappingHandlerAdapter getRequestMappingHandlerAdapter() {
|
||||||
|
return new WebFluxAutoConfigurationTests.MyRequestMappingHandlerAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MyRequestMappingHandlerAdapter
|
||||||
|
extends RequestMappingHandlerAdapter {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Import({ WebFluxAutoConfigurationTests.CustomRequestMappingHandlerMapping.class,
|
||||||
|
WebFluxAutoConfigurationTests.CustomRequestMappingHandlerAdapter.class })
|
||||||
|
static class MultipleWebFluxRegistrations {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class CustomRequestMappingHandlerMapping {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public WebFluxRegistrations webMvcRegistrationsHandlerMapping() {
|
||||||
|
return new WebFluxRegistrations() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
|
||||||
|
return new MyRequestMappingHandlerMapping();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MyRequestMappingHandlerMapping
|
||||||
|
extends RequestMappingHandlerMapping {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue