diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/PrimaryDefaultValidatorPostProcessor.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/PrimaryDefaultValidatorPostProcessor.java index f60b1cdf4df..7fbafabf209 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/PrimaryDefaultValidatorPostProcessor.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/PrimaryDefaultValidatorPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2021 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. @@ -19,8 +19,6 @@ package org.springframework.boot.autoconfigure.validation; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; @@ -39,6 +37,7 @@ import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; * * @author Stephane Nicoll * @author Matej Nedic + * @author Andy Wilkinson */ class PrimaryDefaultValidatorPostProcessor implements ImportBeanDefinitionRegistrar, BeanFactoryAware { @@ -80,10 +79,9 @@ class PrimaryDefaultValidatorPostProcessor implements ImportBeanDefinitionRegist } private boolean hasPrimarySpringValidator() { - String[] validatorBeans = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Validator.class, - false, false); + String[] validatorBeans = this.beanFactory.getBeanNamesForType(Validator.class, false, false); for (String validatorBean : validatorBeans) { - BeanDefinition definition = searchForBeanDefinition(this.beanFactory, validatorBean); + BeanDefinition definition = this.beanFactory.getBeanDefinition(validatorBean); if (definition.isPrimary()) { return true; } @@ -91,15 +89,4 @@ class PrimaryDefaultValidatorPostProcessor implements ImportBeanDefinitionRegist return false; } - private BeanDefinition searchForBeanDefinition(ConfigurableListableBeanFactory clbf, String validatorBean) { - if (clbf.containsLocalBean(validatorBean)) { - return clbf.getBeanDefinition(validatorBean); - } - else if (clbf.getParentBeanFactory() instanceof ConfigurableListableBeanFactory) { - return searchForBeanDefinition((ConfigurableListableBeanFactory) clbf.getParentBeanFactory(), - validatorBean); - } - throw new NoSuchBeanDefinitionException(validatorBean); - } - } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationTests.java index 35df630d129..f87959495ee 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationTests.java @@ -26,6 +26,7 @@ import javax.validation.constraints.Size; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -127,6 +128,37 @@ class ValidationAutoConfigurationTests { }); } + @Test + void whenUserProvidesSpringValidatorInParentContextThenAutoConfiguredValidatorIsPrimary() { + new ApplicationContextRunner().withUserConfiguration(UserDefinedSpringValidatorConfig.class).run((parent) -> { + this.contextRunner.withParent(parent).run((context) -> { + assertThat(context.getBeanNamesForType(Validator.class)).containsExactly("defaultValidator"); + assertThat(context.getBeanNamesForType(org.springframework.validation.Validator.class)) + .containsExactly("defaultValidator"); + assertThat(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context.getBeanFactory(), + org.springframework.validation.Validator.class)).containsExactly("defaultValidator", + "customValidator", "anotherCustomValidator"); + assertThat(isPrimaryBean(context, "defaultValidator")).isTrue(); + }); + }); + } + + @Test + void whenUserProvidesPrimarySpringValidatorInParentContextThenAutoConfiguredValidatorIsPrimary() { + new ApplicationContextRunner().withUserConfiguration(UserDefinedPrimarySpringValidatorConfig.class) + .run((parent) -> { + this.contextRunner.withParent(parent).run((context) -> { + assertThat(context.getBeanNamesForType(Validator.class)).containsExactly("defaultValidator"); + assertThat(context.getBeanNamesForType(org.springframework.validation.Validator.class)) + .containsExactly("defaultValidator"); + assertThat(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context.getBeanFactory(), + org.springframework.validation.Validator.class)).containsExactly("defaultValidator", + "customValidator", "anotherCustomValidator"); + assertThat(isPrimaryBean(context, "defaultValidator")).isTrue(); + }); + }); + } + @Test void validationIsEnabled() { this.contextRunner.withUserConfiguration(SampleService.class).run((context) -> {