Make sure Web infrastructure uses qualified beans

This commit is a follow-up of a change in Spring Framework[1] to make
sure injection points that are expecting a specific bean by name use
a qualifier.

As a result of this change, MVC uses the dedicated MVC validator again
rather than the general one auto-configured by Spring Boot.

[1] https://github.com/spring-projects/spring-framework/issues/23887

Closes gh-18672
pull/18826/head
Stephane Nicoll 5 years ago
parent 3236dfd7d9
commit 7f509bf84e

@ -33,6 +33,7 @@ import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@ -362,10 +363,11 @@ public class WebMvcAutoConfiguration {
@Bean
@Override
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
ContentNegotiationManager mvcContentNegotiationManager,
FormattingConversionService mvcConversionService, Validator mvcValidator) {
RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter(mvcContentNegotiationManager,
mvcConversionService, mvcValidator);
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcValidator") Validator validator) {
RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter(contentNegotiationManager,
conversionService, validator);
adapter.setIgnoreDefaultModelOnRedirect(
this.mvcProperties == null || this.mvcProperties.isIgnoreDefaultModelOnRedirect());
return adapter;
@ -383,11 +385,12 @@ public class WebMvcAutoConfiguration {
@Primary
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping(
ContentNegotiationManager mvcContentNegotiationManager,
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
// Must be @Primary for MvcUriComponentsBuilder to work
return super.requestMappingHandlerMapping(mvcContentNegotiationManager, mvcConversionService,
mvcResourceUrlProvider);
return super.requestMappingHandlerMapping(contentNegotiationManager, conversionService,
resourceUrlProvider);
}
@Bean

@ -564,15 +564,31 @@ class WebMvcAutoConfigurationTests {
}
@Test
void validatorWithConfigurerShouldUseSpringValidator() {
void validatorWithConfigurerAloneShouldUseSpringValidator() {
this.contextRunner.withUserConfiguration(MvcValidator.class).run((context) -> {
assertThat(context).doesNotHaveBean(ValidatorFactory.class);
assertThat(context).doesNotHaveBean(javax.validation.Validator.class);
assertThat(context).getBeanNames(Validator.class).containsOnly("mvcValidator");
assertThat(context.getBean("mvcValidator")).isSameAs(context.getBean(MvcValidator.class).validator);
Validator expectedValidator = context.getBean(MvcValidator.class).validator;
assertThat(context.getBean("mvcValidator")).isSameAs(expectedValidator);
assertThat(context.getBean(RequestMappingHandlerAdapter.class).getWebBindingInitializer())
.hasFieldOrPropertyWithValue("validator", expectedValidator);
});
}
@Test
void validatorWithConfigurerShouldUseSpringValidator() {
this.contextRunner.withConfiguration(AutoConfigurations.of(ValidationAutoConfiguration.class))
.withUserConfiguration(MvcValidator.class).run((context) -> {
assertThat(context).getBeanNames(javax.validation.Validator.class).containsOnly("defaultValidator");
assertThat(context).getBeanNames(Validator.class).containsOnly("defaultValidator", "mvcValidator");
Validator expectedValidator = context.getBean(MvcValidator.class).validator;
assertThat(context.getBean("mvcValidator")).isSameAs(expectedValidator);
assertThat(context.getBean(RequestMappingHandlerAdapter.class).getWebBindingInitializer())
.hasFieldOrPropertyWithValue("validator", expectedValidator);
});
}
@Test
void validatorWithConfigurerDoesNotExposeJsr303() {
this.contextRunner.withUserConfiguration(MvcJsr303Validator.class).run((context) -> {

Loading…
Cancel
Save