diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.java index 6f6c23839956..034170ca7dc6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.java @@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnResource; +import org.springframework.boot.autoconfigure.condition.SearchStrategy; import org.springframework.boot.validation.MessageInterpolatorFactory; import org.springframework.boot.validation.beanvalidation.FilteredMethodValidationPostProcessor; import org.springframework.boot.validation.beanvalidation.MethodValidationExcludeFilter; @@ -63,7 +64,7 @@ public static LocalValidatorFactoryBean defaultValidator(ApplicationContext appl } @Bean - @ConditionalOnMissingBean + @ConditionalOnMissingBean(search = SearchStrategy.CURRENT) public static MethodValidationPostProcessor methodValidationPostProcessor(Environment environment, @Lazy Validator validator, ObjectProvider excludeFilters) { FilteredMethodValidationPostProcessor processor = new FilteredMethodValidationPostProcessor( 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 d0533993045f..30ce1a4bddb2 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 @@ -34,7 +34,6 @@ import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.validation.beanvalidation.MethodValidationExcludeFilter; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; @@ -58,9 +57,8 @@ */ class ValidationAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner( - AnnotationConfigApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ValidationAutoConfiguration.class)); + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ValidationAutoConfiguration.class)); @Test void validationAutoConfigurationShouldConfigureDefaultValidator() { @@ -224,6 +222,20 @@ void methodValidationPostProcessorValidatorDependencyDoesNotTriggerEarlyInitiali .contains("someService")); } + @Test + void validationIsEnabledInChildContext() { + this.contextRunner.run((parent) -> new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ValidationAutoConfiguration.class)) + .withUserConfiguration(SampleService.class).withParent(parent).run((context) -> { + assertThat(context.getBeansOfType(Validator.class)).hasSize(0); + assertThat(parent.getBeansOfType(Validator.class)).hasSize(1); + SampleService service = context.getBean(SampleService.class); + service.doSomething("Valid"); + assertThatExceptionOfType(ConstraintViolationException.class) + .isThrownBy(() -> service.doSomething("KO")); + })); + } + private boolean isPrimaryBean(AssertableApplicationContext context, String beanName) { return ((BeanDefinitionRegistry) context.getSourceApplicationContext()).getBeanDefinition(beanName).isPrimary(); }