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.result.method.HandlerMethodArgumentResolver; | ||||
| 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; | ||||
| 
 | ||||
| /** | ||||
|  | @ -226,8 +228,12 @@ public class WebFluxAutoConfiguration { | |||
| 
 | ||||
| 		private final WebFluxProperties webFluxProperties; | ||||
| 
 | ||||
| 		public EnableWebFluxConfiguration(WebFluxProperties webFluxProperties) { | ||||
| 		private final WebFluxRegistrations webFluxRegistrations; | ||||
| 
 | ||||
| 		public EnableWebFluxConfiguration(WebFluxProperties webFluxProperties, | ||||
| 				ObjectProvider<WebFluxRegistrations> webFluxRegistrations) { | ||||
| 			this.webFluxProperties = webFluxProperties; | ||||
| 			this.webFluxRegistrations = webFluxRegistrations.getIfUnique(); | ||||
| 		} | ||||
| 
 | ||||
| 		@Bean | ||||
|  | @ -249,6 +255,24 @@ public class WebFluxAutoConfiguration { | |||
| 			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 | ||||
|  |  | |||
|  | @ -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.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.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 | ||||
| 	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