Add qualified injection points for MVC and WebFlux infrastructure
Previously, the infrastructure provided by WebMvcConfigurationSupport and WebFluxConfigurationSupport can lead to unexpected results due to the lack of qualifier for certain dependencies. Those configuration classes refer to very specific beans, yet their injection points do not define such qualifiers. As a result, if a candidate exists for the requested type, the context will inject the existing bean and will ignore a most specific one as such constraint it not defined. This can be easily reproduced by having a primary Validator whereas a dedicated "mvcValidator" is expected. Note that a parameter name is in no way a constraint as the name is only used as a fallback when a single candidate cannot be determined. This commit provides explicit @Qualifier metadata for such injection points, renaming the parameter name in the process to clarify that it isn't relevant for the proper bean to be resolved by the context. Closes gh-23887
This commit is contained in:
parent
19ff7d84ab
commit
8d88e29173
|
@ -24,6 +24,7 @@ import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.BeanInitializationException;
|
import org.springframework.beans.factory.BeanInitializationException;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextAware;
|
import org.springframework.context.ApplicationContextAware;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
@ -120,10 +121,10 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public RequestMappingHandlerMapping requestMappingHandlerMapping(
|
public RequestMappingHandlerMapping requestMappingHandlerMapping(
|
||||||
RequestedContentTypeResolver webFluxContentTypeResolver) {
|
@Qualifier("webFluxContentTypeResolver") RequestedContentTypeResolver contentTypeResolver) {
|
||||||
RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
|
RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
|
||||||
mapping.setOrder(0);
|
mapping.setOrder(0);
|
||||||
mapping.setContentTypeResolver(webFluxContentTypeResolver);
|
mapping.setContentTypeResolver(contentTypeResolver);
|
||||||
mapping.setCorsConfigurations(getCorsConfigurations());
|
mapping.setCorsConfigurations(getCorsConfigurations());
|
||||||
|
|
||||||
PathMatchConfigurer configurer = getPathMatchConfigurer();
|
PathMatchConfigurer configurer = getPathMatchConfigurer();
|
||||||
|
@ -265,14 +266,14 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
|
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
|
||||||
ReactiveAdapterRegistry webFluxAdapterRegistry,
|
@Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry,
|
||||||
ServerCodecConfigurer serverCodecConfigurer,
|
ServerCodecConfigurer serverCodecConfigurer,
|
||||||
FormattingConversionService webFluxConversionService,
|
@Qualifier("webFluxConversionService") FormattingConversionService conversionService,
|
||||||
Validator webfluxValidator) {
|
@Qualifier("webFluxValidator") Validator validator) {
|
||||||
RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
|
RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
|
||||||
adapter.setMessageReaders(serverCodecConfigurer.getReaders());
|
adapter.setMessageReaders(serverCodecConfigurer.getReaders());
|
||||||
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer(webFluxConversionService, webfluxValidator));
|
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer(conversionService, validator));
|
||||||
adapter.setReactiveAdapterRegistry(webFluxAdapterRegistry);
|
adapter.setReactiveAdapterRegistry(reactiveAdapterRegistry);
|
||||||
|
|
||||||
ArgumentResolverConfigurer configurer = new ArgumentResolverConfigurer();
|
ArgumentResolverConfigurer configurer = new ArgumentResolverConfigurer();
|
||||||
configureArgumentResolvers(configurer);
|
configureArgumentResolvers(configurer);
|
||||||
|
@ -426,30 +427,30 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ResponseEntityResultHandler responseEntityResultHandler(
|
public ResponseEntityResultHandler responseEntityResultHandler(
|
||||||
ReactiveAdapterRegistry webFluxAdapterRegistry,
|
@Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry,
|
||||||
ServerCodecConfigurer serverCodecConfigurer,
|
ServerCodecConfigurer serverCodecConfigurer,
|
||||||
RequestedContentTypeResolver webFluxContentTypeResolver) {
|
@Qualifier("webFluxContentTypeResolver") RequestedContentTypeResolver contentTypeResolver) {
|
||||||
return new ResponseEntityResultHandler(serverCodecConfigurer.getWriters(),
|
return new ResponseEntityResultHandler(serverCodecConfigurer.getWriters(),
|
||||||
webFluxContentTypeResolver, webFluxAdapterRegistry);
|
contentTypeResolver, reactiveAdapterRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ResponseBodyResultHandler responseBodyResultHandler(
|
public ResponseBodyResultHandler responseBodyResultHandler(
|
||||||
ReactiveAdapterRegistry webFluxAdapterRegistry,
|
@Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry,
|
||||||
ServerCodecConfigurer serverCodecConfigurer,
|
ServerCodecConfigurer serverCodecConfigurer,
|
||||||
RequestedContentTypeResolver webFluxContentTypeResolver) {
|
@Qualifier("webFluxContentTypeResolver") RequestedContentTypeResolver contentTypeResolver) {
|
||||||
return new ResponseBodyResultHandler(serverCodecConfigurer.getWriters(),
|
return new ResponseBodyResultHandler(serverCodecConfigurer.getWriters(),
|
||||||
webFluxContentTypeResolver, webFluxAdapterRegistry);
|
contentTypeResolver, reactiveAdapterRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ViewResolutionResultHandler viewResolutionResultHandler(
|
public ViewResolutionResultHandler viewResolutionResultHandler(
|
||||||
ReactiveAdapterRegistry webFluxAdapterRegistry,
|
@Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry,
|
||||||
RequestedContentTypeResolver webFluxContentTypeResolver) {
|
@Qualifier("webFluxContentTypeResolver") RequestedContentTypeResolver contentTypeResolver) {
|
||||||
ViewResolverRegistry registry = getViewResolverRegistry();
|
ViewResolverRegistry registry = getViewResolverRegistry();
|
||||||
List<ViewResolver> resolvers = registry.getViewResolvers();
|
List<ViewResolver> resolvers = registry.getViewResolvers();
|
||||||
ViewResolutionResultHandler handler = new ViewResolutionResultHandler(
|
ViewResolutionResultHandler handler = new ViewResolutionResultHandler(
|
||||||
resolvers, webFluxContentTypeResolver, webFluxAdapterRegistry);
|
resolvers, contentTypeResolver, reactiveAdapterRegistry);
|
||||||
handler.setDefaultViews(registry.getDefaultViews());
|
handler.setDefaultViews(registry.getDefaultViews());
|
||||||
handler.setOrder(registry.getOrder());
|
handler.setOrder(registry.getOrder());
|
||||||
return handler;
|
return handler;
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2019 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
|
||||||
|
*
|
||||||
|
* https://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.web.reactive.config;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
import org.springframework.core.ReactiveAdapterRegistry;
|
||||||
|
import org.springframework.format.support.FormattingConversionService;
|
||||||
|
import org.springframework.validation.Validator;
|
||||||
|
import org.springframework.web.reactive.accept.RequestedContentTypeResolver;
|
||||||
|
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
|
||||||
|
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
|
||||||
|
import org.springframework.web.reactive.result.method.annotation.ResponseBodyResultHandler;
|
||||||
|
import org.springframework.web.reactive.result.method.annotation.ResponseEntityResultHandler;
|
||||||
|
import org.springframework.web.reactive.result.view.ViewResolutionResultHandler;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration tests for {@link DelegatingWebFluxConfiguration}.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
public class DelegatingWebFluxConfigurationIntegrationTests {
|
||||||
|
|
||||||
|
private AnnotationConfigApplicationContext context;
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void closeContext() {
|
||||||
|
if (this.context != null) {
|
||||||
|
this.context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestMappingHandlerMappingUsesWebFluxInfrastructureByDefault() {
|
||||||
|
load(context -> { });
|
||||||
|
RequestMappingHandlerMapping handlerMapping = this.context.getBean(RequestMappingHandlerMapping.class);
|
||||||
|
assertThat(handlerMapping.getContentTypeResolver()).isSameAs(this.context.getBean("webFluxContentTypeResolver"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestMappingHandlerMappingWithPrimaryUsesQualifiedRequestedContentTypeResolver() {
|
||||||
|
load(registerPrimaryBean("testContentTypeResolver", RequestedContentTypeResolver.class));
|
||||||
|
RequestMappingHandlerMapping handlerMapping = this.context.getBean(RequestMappingHandlerMapping.class);
|
||||||
|
assertThat(handlerMapping.getContentTypeResolver()).isSameAs(this.context.getBean("webFluxContentTypeResolver"));
|
||||||
|
assertThat(this.context.getBeansOfType(RequestedContentTypeResolver.class)).containsOnlyKeys(
|
||||||
|
"webFluxContentTypeResolver", "testContentTypeResolver");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestMappingHandlerAdapterUsesWebFluxInfrastructureByDefault() {
|
||||||
|
load(context -> { });
|
||||||
|
RequestMappingHandlerAdapter mappingHandlerAdapter = this.context.getBean(RequestMappingHandlerAdapter.class);
|
||||||
|
assertThat(mappingHandlerAdapter.getReactiveAdapterRegistry()).isSameAs(this.context.getBean("webFluxAdapterRegistry"));
|
||||||
|
assertThat(mappingHandlerAdapter.getWebBindingInitializer()).hasFieldOrPropertyWithValue("conversionService",
|
||||||
|
this.context.getBean("webFluxConversionService"));
|
||||||
|
assertThat(mappingHandlerAdapter.getWebBindingInitializer()).hasFieldOrPropertyWithValue("validator",
|
||||||
|
this.context.getBean("webFluxValidator"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestMappingHandlerAdapterWithPrimaryUsesQualifiedReactiveAdapterRegistry() {
|
||||||
|
load(registerPrimaryBean("testReactiveAdapterRegistry", ReactiveAdapterRegistry.class));
|
||||||
|
RequestMappingHandlerAdapter mappingHandlerAdapter = this.context.getBean(RequestMappingHandlerAdapter.class);
|
||||||
|
assertThat(mappingHandlerAdapter.getReactiveAdapterRegistry()).isSameAs(this.context.getBean("webFluxAdapterRegistry"));
|
||||||
|
assertThat(this.context.getBeansOfType(ReactiveAdapterRegistry.class)).containsOnlyKeys(
|
||||||
|
"webFluxAdapterRegistry", "testReactiveAdapterRegistry");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestMappingHandlerAdapterWithPrimaryUsesQualifiedConversionService() {
|
||||||
|
load(registerPrimaryBean("testConversionService", FormattingConversionService.class));
|
||||||
|
RequestMappingHandlerAdapter mappingHandlerAdapter = this.context.getBean(RequestMappingHandlerAdapter.class);
|
||||||
|
assertThat(mappingHandlerAdapter.getWebBindingInitializer()).hasFieldOrPropertyWithValue("conversionService",
|
||||||
|
this.context.getBean("webFluxConversionService"));
|
||||||
|
assertThat(this.context.getBeansOfType(FormattingConversionService.class)).containsOnlyKeys(
|
||||||
|
"webFluxConversionService", "testConversionService");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestMappingHandlerAdapterWithPrimaryUsesQualifiedValidator() {
|
||||||
|
load(registerPrimaryBean("testValidator", Validator.class));
|
||||||
|
RequestMappingHandlerAdapter mappingHandlerAdapter = this.context.getBean(RequestMappingHandlerAdapter.class);
|
||||||
|
assertThat(mappingHandlerAdapter.getWebBindingInitializer()).hasFieldOrPropertyWithValue("validator",
|
||||||
|
this.context.getBean("webFluxValidator"));
|
||||||
|
assertThat(this.context.getBeansOfType(Validator.class)).containsOnlyKeys(
|
||||||
|
"webFluxValidator", "testValidator");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void responseEntityResultHandlerUsesWebFluxInfrastructureByDefault() {
|
||||||
|
load(context -> { });
|
||||||
|
ResponseEntityResultHandler responseEntityResultHandler = this.context.getBean(ResponseEntityResultHandler.class);
|
||||||
|
assertThat(responseEntityResultHandler.getAdapterRegistry()).isSameAs(this.context.getBean("webFluxAdapterRegistry"));
|
||||||
|
assertThat(responseEntityResultHandler.getContentTypeResolver()).isSameAs(this.context.getBean("webFluxContentTypeResolver"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void responseEntityResultHandlerWithPrimaryUsesQualifiedReactiveAdapterRegistry() {
|
||||||
|
load(registerPrimaryBean("testReactiveAdapterRegistry", ReactiveAdapterRegistry.class));
|
||||||
|
ResponseEntityResultHandler responseEntityResultHandler = this.context.getBean(ResponseEntityResultHandler.class);
|
||||||
|
assertThat(responseEntityResultHandler.getAdapterRegistry()).isSameAs(this.context.getBean("webFluxAdapterRegistry"));
|
||||||
|
assertThat(this.context.getBeansOfType(ReactiveAdapterRegistry.class)).containsOnlyKeys(
|
||||||
|
"webFluxAdapterRegistry", "testReactiveAdapterRegistry");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void responseEntityResultHandlerWithPrimaryUsesQualifiedRequestedContentTypeResolver() {
|
||||||
|
load(registerPrimaryBean("testContentTypeResolver", RequestedContentTypeResolver.class));
|
||||||
|
ResponseEntityResultHandler responseEntityResultHandler = this.context.getBean(ResponseEntityResultHandler.class);
|
||||||
|
assertThat(responseEntityResultHandler.getContentTypeResolver()).isSameAs(this.context.getBean("webFluxContentTypeResolver"));
|
||||||
|
assertThat(this.context.getBeansOfType(RequestedContentTypeResolver.class)).containsOnlyKeys(
|
||||||
|
"webFluxContentTypeResolver", "testContentTypeResolver");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void responseBodyResultHandlerUsesWebFluxInfrastructureByDefault() {
|
||||||
|
load(context -> { });
|
||||||
|
ResponseBodyResultHandler responseBodyResultHandler = this.context.getBean(ResponseBodyResultHandler.class);
|
||||||
|
assertThat(responseBodyResultHandler.getAdapterRegistry()).isSameAs(this.context.getBean("webFluxAdapterRegistry"));
|
||||||
|
assertThat(responseBodyResultHandler.getContentTypeResolver()).isSameAs(this.context.getBean("webFluxContentTypeResolver"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void responseBodyResultHandlerWithPrimaryUsesQualifiedReactiveAdapterRegistry() {
|
||||||
|
load(registerPrimaryBean("testReactiveAdapterRegistry", ReactiveAdapterRegistry.class));
|
||||||
|
ResponseBodyResultHandler responseBodyResultHandler = this.context.getBean(ResponseBodyResultHandler.class);
|
||||||
|
assertThat(responseBodyResultHandler.getAdapterRegistry()).isSameAs(this.context.getBean("webFluxAdapterRegistry"));
|
||||||
|
assertThat(this.context.getBeansOfType(ReactiveAdapterRegistry.class)).containsOnlyKeys(
|
||||||
|
"webFluxAdapterRegistry", "testReactiveAdapterRegistry");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void responseBodyResultHandlerWithPrimaryUsesQualifiedRequestedContentTypeResolver() {
|
||||||
|
load(registerPrimaryBean("testContentTypeResolver", RequestedContentTypeResolver.class));
|
||||||
|
ResponseBodyResultHandler responseBodyResultHandler = this.context.getBean(ResponseBodyResultHandler.class);
|
||||||
|
assertThat(responseBodyResultHandler.getContentTypeResolver()).isSameAs(this.context.getBean("webFluxContentTypeResolver"));
|
||||||
|
assertThat(this.context.getBeansOfType(RequestedContentTypeResolver.class)).containsOnlyKeys(
|
||||||
|
"webFluxContentTypeResolver", "testContentTypeResolver");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void viewResolutionResultHandlerUsesWebFluxInfrastructureByDefault() {
|
||||||
|
load(context -> { });
|
||||||
|
ViewResolutionResultHandler viewResolutionResultHandler = this.context.getBean(ViewResolutionResultHandler.class);
|
||||||
|
assertThat(viewResolutionResultHandler.getAdapterRegistry()).isSameAs(this.context.getBean("webFluxAdapterRegistry"));
|
||||||
|
assertThat(viewResolutionResultHandler.getContentTypeResolver()).isSameAs(this.context.getBean("webFluxContentTypeResolver"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void viewResolutionResultHandlerWithPrimaryUsesQualifiedReactiveAdapterRegistry() {
|
||||||
|
load(registerPrimaryBean("testReactiveAdapterRegistry", ReactiveAdapterRegistry.class));
|
||||||
|
ViewResolutionResultHandler viewResolutionResultHandler = this.context.getBean(ViewResolutionResultHandler.class);
|
||||||
|
assertThat(viewResolutionResultHandler.getAdapterRegistry()).isSameAs(this.context.getBean("webFluxAdapterRegistry"));
|
||||||
|
assertThat(this.context.getBeansOfType(ReactiveAdapterRegistry.class)).containsOnlyKeys(
|
||||||
|
"webFluxAdapterRegistry", "testReactiveAdapterRegistry");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void viewResolutionResultHandlerWithPrimaryUsesQualifiedRequestedContentTypeResolver() {
|
||||||
|
load(registerPrimaryBean("testContentTypeResolver", RequestedContentTypeResolver.class));
|
||||||
|
ViewResolutionResultHandler viewResolutionResultHandler = this.context.getBean(ViewResolutionResultHandler.class);
|
||||||
|
assertThat(viewResolutionResultHandler.getContentTypeResolver()).isSameAs(this.context.getBean("webFluxContentTypeResolver"));
|
||||||
|
assertThat(this.context.getBeansOfType(RequestedContentTypeResolver.class)).containsOnlyKeys(
|
||||||
|
"webFluxContentTypeResolver", "testContentTypeResolver");
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Consumer<AnnotationConfigApplicationContext> registerPrimaryBean(String beanName, Class<T> type) {
|
||||||
|
return context -> context.registerBean(beanName, type, () -> mock(type), definition -> definition.setPrimary(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void load(Consumer<AnnotationConfigApplicationContext> context) {
|
||||||
|
AnnotationConfigApplicationContext testContext = new AnnotationConfigApplicationContext();
|
||||||
|
context.accept(testContext);
|
||||||
|
testContext.registerBean(DelegatingWebFluxConfiguration.class);
|
||||||
|
testContext.refresh();
|
||||||
|
this.context = testContext;
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ import javax.servlet.ServletContext;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||||
import org.springframework.beans.factory.BeanInitializationException;
|
import org.springframework.beans.factory.BeanInitializationException;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextAware;
|
import org.springframework.context.ApplicationContextAware;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
@ -275,13 +276,14 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public RequestMappingHandlerMapping requestMappingHandlerMapping(
|
public RequestMappingHandlerMapping requestMappingHandlerMapping(
|
||||||
ContentNegotiationManager mvcContentNegotiationManager,
|
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
|
||||||
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
|
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
|
||||||
|
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
|
||||||
|
|
||||||
RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
|
RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
|
||||||
mapping.setOrder(0);
|
mapping.setOrder(0);
|
||||||
mapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
|
mapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
|
||||||
mapping.setContentNegotiationManager(mvcContentNegotiationManager);
|
mapping.setContentNegotiationManager(contentNegotiationManager);
|
||||||
mapping.setCorsConfigurations(getCorsConfigurations());
|
mapping.setCorsConfigurations(getCorsConfigurations());
|
||||||
|
|
||||||
PathMatchConfigurer configurer = getPathMatchConfigurer();
|
PathMatchConfigurer configurer = getPathMatchConfigurer();
|
||||||
|
@ -447,10 +449,11 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@Nullable
|
@Nullable
|
||||||
public HandlerMapping viewControllerHandlerMapping(PathMatcher mvcPathMatcher,
|
public HandlerMapping viewControllerHandlerMapping(
|
||||||
UrlPathHelper mvcUrlPathHelper,
|
@Qualifier("mvcPathMatcher") PathMatcher pathMatcher,
|
||||||
FormattingConversionService mvcConversionService,
|
@Qualifier("mvcUrlPathHelper") UrlPathHelper urlPathHelper,
|
||||||
ResourceUrlProvider mvcResourceUrlProvider) {
|
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
|
||||||
|
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
|
||||||
ViewControllerRegistry registry = new ViewControllerRegistry(this.applicationContext);
|
ViewControllerRegistry registry = new ViewControllerRegistry(this.applicationContext);
|
||||||
addViewControllers(registry);
|
addViewControllers(registry);
|
||||||
|
|
||||||
|
@ -458,9 +461,9 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
if (handlerMapping == null) {
|
if (handlerMapping == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
handlerMapping.setPathMatcher(mvcPathMatcher);
|
handlerMapping.setPathMatcher(pathMatcher);
|
||||||
handlerMapping.setUrlPathHelper(mvcUrlPathHelper);
|
handlerMapping.setUrlPathHelper(urlPathHelper);
|
||||||
handlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
|
handlerMapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
|
||||||
handlerMapping.setCorsConfigurations(getCorsConfigurations());
|
handlerMapping.setCorsConfigurations(getCorsConfigurations());
|
||||||
return handlerMapping;
|
return handlerMapping;
|
||||||
}
|
}
|
||||||
|
@ -478,11 +481,12 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public BeanNameUrlHandlerMapping beanNameHandlerMapping(
|
public BeanNameUrlHandlerMapping beanNameHandlerMapping(
|
||||||
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
|
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
|
||||||
|
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
|
||||||
|
|
||||||
BeanNameUrlHandlerMapping mapping = new BeanNameUrlHandlerMapping();
|
BeanNameUrlHandlerMapping mapping = new BeanNameUrlHandlerMapping();
|
||||||
mapping.setOrder(2);
|
mapping.setOrder(2);
|
||||||
mapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
|
mapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
|
||||||
mapping.setCorsConfigurations(getCorsConfigurations());
|
mapping.setCorsConfigurations(getCorsConfigurations());
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
@ -500,11 +504,12 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public RouterFunctionMapping routerFunctionMapping(
|
public RouterFunctionMapping routerFunctionMapping(
|
||||||
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
|
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
|
||||||
|
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
|
||||||
|
|
||||||
RouterFunctionMapping mapping = new RouterFunctionMapping();
|
RouterFunctionMapping mapping = new RouterFunctionMapping();
|
||||||
mapping.setOrder(3);
|
mapping.setOrder(3);
|
||||||
mapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
|
mapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
|
||||||
mapping.setCorsConfigurations(getCorsConfigurations());
|
mapping.setCorsConfigurations(getCorsConfigurations());
|
||||||
mapping.setMessageConverters(getMessageConverters());
|
mapping.setMessageConverters(getMessageConverters());
|
||||||
return mapping;
|
return mapping;
|
||||||
|
@ -517,24 +522,27 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@Nullable
|
@Nullable
|
||||||
public HandlerMapping resourceHandlerMapping(UrlPathHelper mvcUrlPathHelper,
|
public HandlerMapping resourceHandlerMapping(
|
||||||
PathMatcher mvcPathMatcher, ContentNegotiationManager mvcContentNegotiationManager,
|
@Qualifier("mvcUrlPathHelper") UrlPathHelper urlPathHelper,
|
||||||
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
|
@Qualifier("mvcPathMatcher") PathMatcher pathMatcher,
|
||||||
|
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
|
||||||
|
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
|
||||||
|
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
|
||||||
|
|
||||||
Assert.state(this.applicationContext != null, "No ApplicationContext set");
|
Assert.state(this.applicationContext != null, "No ApplicationContext set");
|
||||||
Assert.state(this.servletContext != null, "No ServletContext set");
|
Assert.state(this.servletContext != null, "No ServletContext set");
|
||||||
|
|
||||||
ResourceHandlerRegistry registry = new ResourceHandlerRegistry(this.applicationContext,
|
ResourceHandlerRegistry registry = new ResourceHandlerRegistry(this.applicationContext,
|
||||||
this.servletContext, mvcContentNegotiationManager, mvcUrlPathHelper);
|
this.servletContext, contentNegotiationManager, urlPathHelper);
|
||||||
addResourceHandlers(registry);
|
addResourceHandlers(registry);
|
||||||
|
|
||||||
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
|
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
|
||||||
if (handlerMapping == null) {
|
if (handlerMapping == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
handlerMapping.setPathMatcher(mvcPathMatcher);
|
handlerMapping.setPathMatcher(pathMatcher);
|
||||||
handlerMapping.setUrlPathHelper(mvcUrlPathHelper);
|
handlerMapping.setUrlPathHelper(urlPathHelper);
|
||||||
handlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
|
handlerMapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
|
||||||
handlerMapping.setCorsConfigurations(getCorsConfigurations());
|
handlerMapping.setCorsConfigurations(getCorsConfigurations());
|
||||||
return handlerMapping;
|
return handlerMapping;
|
||||||
}
|
}
|
||||||
|
@ -597,13 +605,14 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
|
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
|
||||||
ContentNegotiationManager mvcContentNegotiationManager,
|
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
|
||||||
FormattingConversionService mvcConversionService, Validator mvcValidator) {
|
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
|
||||||
|
@Qualifier("mvcValidator") Validator validator) {
|
||||||
|
|
||||||
RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
|
RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
|
||||||
adapter.setContentNegotiationManager(mvcContentNegotiationManager);
|
adapter.setContentNegotiationManager(contentNegotiationManager);
|
||||||
adapter.setMessageConverters(getMessageConverters());
|
adapter.setMessageConverters(getMessageConverters());
|
||||||
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer(mvcConversionService, mvcValidator));
|
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer(conversionService, validator));
|
||||||
adapter.setCustomArgumentResolvers(getArgumentResolvers());
|
adapter.setCustomArgumentResolvers(getArgumentResolvers());
|
||||||
adapter.setCustomReturnValueHandlers(getReturnValueHandlers());
|
adapter.setCustomReturnValueHandlers(getReturnValueHandlers());
|
||||||
|
|
||||||
|
@ -898,10 +907,10 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public CompositeUriComponentsContributor mvcUriComponentsContributor(
|
public CompositeUriComponentsContributor mvcUriComponentsContributor(
|
||||||
FormattingConversionService mvcConversionService,
|
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
|
||||||
RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
|
@Qualifier("requestMappingHandlerAdapter") RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
|
||||||
return new CompositeUriComponentsContributor(
|
return new CompositeUriComponentsContributor(
|
||||||
requestMappingHandlerAdapter.getArgumentResolvers(), mvcConversionService);
|
requestMappingHandlerAdapter.getArgumentResolvers(), conversionService);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -932,11 +941,11 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public HandlerExceptionResolver handlerExceptionResolver(
|
public HandlerExceptionResolver handlerExceptionResolver(
|
||||||
ContentNegotiationManager mvcContentNegotiationManager) {
|
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager) {
|
||||||
List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<>();
|
List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<>();
|
||||||
configureHandlerExceptionResolvers(exceptionResolvers);
|
configureHandlerExceptionResolvers(exceptionResolvers);
|
||||||
if (exceptionResolvers.isEmpty()) {
|
if (exceptionResolvers.isEmpty()) {
|
||||||
addDefaultHandlerExceptionResolvers(exceptionResolvers, mvcContentNegotiationManager);
|
addDefaultHandlerExceptionResolvers(exceptionResolvers, contentNegotiationManager);
|
||||||
}
|
}
|
||||||
extendHandlerExceptionResolvers(exceptionResolvers);
|
extendHandlerExceptionResolvers(exceptionResolvers);
|
||||||
HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
|
HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
|
||||||
|
@ -1026,9 +1035,10 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public ViewResolver mvcViewResolver(ContentNegotiationManager mvcContentNegotiationManager) {
|
public ViewResolver mvcViewResolver(
|
||||||
|
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager) {
|
||||||
ViewResolverRegistry registry =
|
ViewResolverRegistry registry =
|
||||||
new ViewResolverRegistry(mvcContentNegotiationManager, this.applicationContext);
|
new ViewResolverRegistry(contentNegotiationManager, this.applicationContext);
|
||||||
configureViewResolvers(registry);
|
configureViewResolvers(registry);
|
||||||
|
|
||||||
if (registry.getViewResolvers().isEmpty() && this.applicationContext != null) {
|
if (registry.getViewResolvers().isEmpty() && this.applicationContext != null) {
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2019 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
|
||||||
|
*
|
||||||
|
* https://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.web.servlet.config.annotation;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigUtils;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.convert.ConversionService;
|
||||||
|
import org.springframework.mock.web.test.MockServletContext;
|
||||||
|
import org.springframework.util.PathMatcher;
|
||||||
|
import org.springframework.validation.Validator;
|
||||||
|
import org.springframework.web.accept.ContentNegotiationManager;
|
||||||
|
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||||
|
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||||
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration tests for {@link DelegatingWebMvcConfiguration}.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
public class DelegatingWebMvcConfigurationIntegrationTests {
|
||||||
|
|
||||||
|
private ConfigurableApplicationContext context;
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void closeContext() {
|
||||||
|
if (this.context != null) {
|
||||||
|
this.context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestMappingHandlerMappingUsesMvcInfrastructureByDefault() {
|
||||||
|
load(context -> { });
|
||||||
|
RequestMappingHandlerMapping handlerMapping = this.context.getBean(RequestMappingHandlerMapping.class);
|
||||||
|
assertThat(handlerMapping.getContentNegotiationManager()).isSameAs(this.context.getBean("mvcContentNegotiationManager"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestMappingHandlerMappingWithPrimaryUsesQualifiedContentNegotiationManager() {
|
||||||
|
load(registerPrimaryBean("testContentNegotiationManager", ContentNegotiationManager.class));
|
||||||
|
RequestMappingHandlerMapping handlerMapping = this.context.getBean(RequestMappingHandlerMapping.class);
|
||||||
|
assertThat(handlerMapping.getContentNegotiationManager()).isSameAs(this.context.getBean("mvcContentNegotiationManager"));
|
||||||
|
assertThat(this.context.getBeansOfType(ContentNegotiationManager.class)).containsOnlyKeys(
|
||||||
|
"mvcContentNegotiationManager", "testContentNegotiationManager");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void viewControllerHandlerMappingUsesMvcInfrastructureByDefault() {
|
||||||
|
load(context -> context.registerBean(ViewControllerConfiguration.class));
|
||||||
|
AbstractHandlerMapping handlerMapping = this.context.getBean("viewControllerHandlerMapping", AbstractHandlerMapping.class);
|
||||||
|
assertThat(handlerMapping.getPathMatcher()).isSameAs(this.context.getBean("mvcPathMatcher"));
|
||||||
|
assertThat(handlerMapping.getUrlPathHelper()).isSameAs(this.context.getBean("mvcUrlPathHelper"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void viewControllerHandlerMappingWithPrimaryUsesQualifiedPathMatcher() {
|
||||||
|
load(registerPrimaryBean("testPathMatcher", PathMatcher.class)
|
||||||
|
.andThen(context -> context.registerBean(ViewControllerConfiguration.class)));
|
||||||
|
AbstractHandlerMapping handlerMapping = this.context.getBean("viewControllerHandlerMapping", AbstractHandlerMapping.class);
|
||||||
|
assertThat(handlerMapping.getPathMatcher()).isSameAs(this.context.getBean("mvcPathMatcher"));
|
||||||
|
assertThat(this.context.getBeansOfType(PathMatcher.class)).containsOnlyKeys(
|
||||||
|
"mvcPathMatcher", "testPathMatcher");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void viewControllerHandlerMappingWithPrimaryUsesQualifiedUrlPathHelper() {
|
||||||
|
load(registerPrimaryBean("testUrlPathHelper", UrlPathHelper.class)
|
||||||
|
.andThen(context -> context.registerBean(ViewControllerConfiguration.class)));
|
||||||
|
AbstractHandlerMapping handlerMapping = this.context.getBean("viewControllerHandlerMapping", AbstractHandlerMapping.class);
|
||||||
|
assertThat(handlerMapping.getUrlPathHelper()).isSameAs(this.context.getBean("mvcUrlPathHelper"));
|
||||||
|
assertThat(this.context.getBeansOfType(UrlPathHelper.class)).containsOnlyKeys(
|
||||||
|
"mvcUrlPathHelper", "testUrlPathHelper");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void resourceHandlerMappingUsesMvcInfrastructureByDefault() {
|
||||||
|
load(context -> context.registerBean(ResourceHandlerConfiguration.class));
|
||||||
|
AbstractHandlerMapping handlerMapping = this.context.getBean("resourceHandlerMapping", AbstractHandlerMapping.class);
|
||||||
|
assertThat(handlerMapping.getPathMatcher()).isSameAs(this.context.getBean("mvcPathMatcher"));
|
||||||
|
assertThat(handlerMapping.getUrlPathHelper()).isSameAs(this.context.getBean("mvcUrlPathHelper"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void resourceHandlerMappingWithPrimaryUsesQualifiedPathMatcher() {
|
||||||
|
load(registerPrimaryBean("testPathMatcher", PathMatcher.class)
|
||||||
|
.andThen(context -> context.registerBean(ResourceHandlerConfiguration.class)));
|
||||||
|
AbstractHandlerMapping handlerMapping = this.context.getBean("resourceHandlerMapping", AbstractHandlerMapping.class);
|
||||||
|
assertThat(handlerMapping.getPathMatcher()).isSameAs(this.context.getBean("mvcPathMatcher"));
|
||||||
|
assertThat(this.context.getBeansOfType(PathMatcher.class)).containsOnlyKeys(
|
||||||
|
"mvcPathMatcher", "testPathMatcher");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void resourceHandlerMappingWithPrimaryUsesQualifiedUrlPathHelper() {
|
||||||
|
load(registerPrimaryBean("testUrlPathHelper", UrlPathHelper.class)
|
||||||
|
.andThen(context -> context.registerBean(ResourceHandlerConfiguration.class)));
|
||||||
|
AbstractHandlerMapping handlerMapping = this.context.getBean("resourceHandlerMapping", AbstractHandlerMapping.class);
|
||||||
|
assertThat(handlerMapping.getUrlPathHelper()).isSameAs(this.context.getBean("mvcUrlPathHelper"));
|
||||||
|
assertThat(this.context.getBeansOfType(UrlPathHelper.class)).containsOnlyKeys(
|
||||||
|
"mvcUrlPathHelper", "testUrlPathHelper");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestMappingHandlerAdapterUsesMvcInfrastructureByDefault() {
|
||||||
|
load(context -> { });
|
||||||
|
RequestMappingHandlerAdapter mappingHandlerAdapter = this.context.getBean(RequestMappingHandlerAdapter.class);
|
||||||
|
assertThat(mappingHandlerAdapter).hasFieldOrPropertyWithValue(
|
||||||
|
"contentNegotiationManager", this.context.getBean("mvcContentNegotiationManager"));
|
||||||
|
assertThat(mappingHandlerAdapter.getWebBindingInitializer()).hasFieldOrPropertyWithValue(
|
||||||
|
"conversionService", this.context.getBean("mvcConversionService"));
|
||||||
|
assertThat(mappingHandlerAdapter.getWebBindingInitializer()).hasFieldOrPropertyWithValue(
|
||||||
|
"validator", this.context.getBean("mvcValidator"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestMappingHandlerAdapterWithPrimaryUsesQualifiedContentNegotiationManager() {
|
||||||
|
load(registerPrimaryBean("testContentNegotiationManager", ContentNegotiationManager.class));
|
||||||
|
RequestMappingHandlerAdapter mappingHandlerAdapter = this.context.getBean(RequestMappingHandlerAdapter.class);
|
||||||
|
assertThat(mappingHandlerAdapter).hasFieldOrPropertyWithValue(
|
||||||
|
"contentNegotiationManager", this.context.getBean("mvcContentNegotiationManager"));
|
||||||
|
assertThat(this.context.getBeansOfType(ContentNegotiationManager.class)).containsOnlyKeys(
|
||||||
|
"mvcContentNegotiationManager", "testContentNegotiationManager");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestMappingHandlerAdapterWithPrimaryUsesQualifiedConversionService() {
|
||||||
|
load(registerPrimaryBean("testConversionService", ConversionService.class));
|
||||||
|
RequestMappingHandlerAdapter mappingHandlerAdapter = this.context.getBean(RequestMappingHandlerAdapter.class);
|
||||||
|
assertThat(mappingHandlerAdapter.getWebBindingInitializer()).hasFieldOrPropertyWithValue(
|
||||||
|
"conversionService", this.context.getBean("mvcConversionService"));
|
||||||
|
assertThat(this.context.getBeansOfType(ConversionService.class)).containsOnlyKeys("mvcConversionService", "testConversionService");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestMappingHandlerAdapterWithPrimaryUsesQualifiedValidator() {
|
||||||
|
load(registerPrimaryBean("testValidator", Validator.class));
|
||||||
|
RequestMappingHandlerAdapter mappingHandlerAdapter = this.context.getBean(RequestMappingHandlerAdapter.class);
|
||||||
|
assertThat(mappingHandlerAdapter.getWebBindingInitializer()).hasFieldOrPropertyWithValue(
|
||||||
|
"validator", this.context.getBean("mvcValidator"));
|
||||||
|
assertThat(this.context.getBeansOfType(Validator.class)).containsOnlyKeys("mvcValidator", "testValidator");
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Consumer<GenericWebApplicationContext> registerPrimaryBean(String beanName, Class<T> type) {
|
||||||
|
return context -> context.registerBean(beanName, type, () -> mock(type), definition -> definition.setPrimary(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void load(Consumer<GenericWebApplicationContext> context) {
|
||||||
|
GenericWebApplicationContext webContext = new GenericWebApplicationContext();
|
||||||
|
AnnotationConfigUtils.registerAnnotationConfigProcessors(webContext);
|
||||||
|
webContext.setServletContext(new MockServletContext());
|
||||||
|
|
||||||
|
context.accept(webContext);
|
||||||
|
webContext.registerBean(DelegatingWebMvcConfiguration.class);
|
||||||
|
webContext.refresh();
|
||||||
|
this.context = webContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class ViewControllerConfiguration implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addViewControllers(ViewControllerRegistry registry) {
|
||||||
|
registry.addViewController("/test");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class ResourceHandlerConfiguration implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||||
|
registry.addResourceHandler("/resources/**");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue