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
This commit is contained in:
@@ -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) -> {
|
||||
|
||||
Reference in New Issue
Block a user