From a7334281506bd5d0557c61986ca0dba933e71efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 20 May 2025 15:57:32 +0200 Subject: [PATCH] Prevent early initialization of binding in ValidationAutoConfiguration This commit replaces the use of ConfigurationProperties in ValidationAutoConfiguration by an explicit environment check, as it was already the case for the spring.aop.proxy-target-class property. Closes gh-45618 --- .../ValidationAutoConfiguration.java | 9 ++- .../validation/ValidationProperties.java | 64 ------------------- ...itional-spring-configuration-metadata.json | 6 ++ .../ValidationAutoConfigurationTests.java | 8 +++ .../validation/ValidationPropertiesTests.java | 38 ----------- 5 files changed, 18 insertions(+), 107 deletions(-) delete mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationProperties.java delete mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationPropertiesTests.java 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 d1af26e17a..2ae0ca0d8d 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 @@ -27,7 +27,6 @@ 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.context.properties.EnableConfigurationProperties; import org.springframework.boot.validation.MessageInterpolatorFactory; import org.springframework.boot.validation.beanvalidation.FilteredMethodValidationPostProcessor; import org.springframework.boot.validation.beanvalidation.MethodValidationExcludeFilter; @@ -51,7 +50,6 @@ import org.springframework.validation.beanvalidation.MethodValidationPostProcess @AutoConfiguration @ConditionalOnClass(ExecutableValidator.class) @ConditionalOnResource(resources = "classpath:META-INF/services/jakarta.validation.spi.ValidationProvider") -@EnableConfigurationProperties(ValidationProperties.class) @Import(PrimaryDefaultValidatorPostProcessor.class) public class ValidationAutoConfiguration { @@ -71,13 +69,14 @@ public class ValidationAutoConfiguration { @Bean @ConditionalOnMissingBean(search = SearchStrategy.CURRENT) public static MethodValidationPostProcessor methodValidationPostProcessor(Environment environment, - ValidationProperties validationProperties, ObjectProvider validator, - ObjectProvider excludeFilters) { + ObjectProvider validator, ObjectProvider excludeFilters) { FilteredMethodValidationPostProcessor processor = new FilteredMethodValidationPostProcessor( excludeFilters.orderedStream()); boolean proxyTargetClass = environment.getProperty("spring.aop.proxy-target-class", Boolean.class, true); processor.setProxyTargetClass(proxyTargetClass); - processor.setAdaptConstraintViolations(validationProperties.getMethod().isAdaptConstraintViolations()); + boolean adaptConstraintViolations = environment + .getProperty("spring.validation.method.adapt-constraint-violations", Boolean.class, false); + processor.setAdaptConstraintViolations(adaptConstraintViolations); processor.setValidatorProvider(validator); return processor; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationProperties.java deleted file mode 100644 index 863ffa2f9b..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationProperties.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2012-2025 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.boot.autoconfigure.validation; - -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Role; - -/** - * {@link ConfigurationProperties @ConfigurationProperties} for validation. - * - * @author Yanming Zhou - * @author Andy Wilkinson - * @since 3.5.0 - */ -@Role(BeanDefinition.ROLE_INFRASTRUCTURE) -@ConfigurationProperties("spring.validation") -public class ValidationProperties { - - private Method method = new Method(); - - public Method getMethod() { - return this.method; - } - - public void setMethod(Method method) { - this.method = method; - } - - /** - * Method validation properties. - */ - public static class Method { - - /** - * Whether to adapt ConstraintViolations to MethodValidationResult. - */ - private boolean adaptConstraintViolations; - - public boolean isAdaptConstraintViolations() { - return this.adaptConstraintViolations; - } - - public void setAdaptConstraintViolations(boolean adaptConstraintViolations) { - this.adaptConstraintViolations = adaptConstraintViolations; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 5e5476281e..741c5444d5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -2861,6 +2861,12 @@ "name": "spring.thymeleaf.suffix", "defaultValue": ".html" }, + { + "name": "spring.validation.method.adapt-constraint-violations", + "type": "java.lang.Boolean", + "description": "Whether to adapt ConstraintViolations to MethodValidationResult.", + "defaultValue": false + }, { "name": "spring.webflux.hiddenmethod.filter.enabled", "type": "java.lang.Boolean", 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 2136c1d991..5defeb70c3 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 @@ -221,6 +221,14 @@ class ValidationAutoConfigurationTests { }); } + @Test + void validationUseDefaultAdaptToConstraintViolationsValue() { + this.contextRunner.withUserConfiguration(AnotherSampleServiceConfiguration.class).run((context) -> { + MethodValidationPostProcessor postProcessor = context.getBean(MethodValidationPostProcessor.class); + assertThat(postProcessor).hasFieldOrPropertyWithValue("adaptConstraintViolations", false); + }); + } + @Test @SuppressWarnings("unchecked") void userDefinedMethodValidationPostProcessorTakesPrecedence() { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationPropertiesTests.java deleted file mode 100644 index d507516c80..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationPropertiesTests.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2012-2025 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.boot.autoconfigure.validation; - -import org.junit.jupiter.api.Test; - -import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ValidationProperties}. - * - * @author Andy Wilkinson - */ -class ValidationPropertiesTests { - - @Test - void adaptConstraintViolationsPropertyDefaultMatchesPostProcessorDefault() { - assertThat(new MethodValidationPostProcessor()).extracting("adaptConstraintViolations") - .isEqualTo(new ValidationProperties().getMethod().isAdaptConstraintViolations()); - } - -}