diff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc
index f97c38c85d..716a0309c2 100644
--- a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc
+++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc
@@ -287,32 +287,7 @@ As the preceding example shows, a `ConstraintValidator` implementation can have
You can integrate the method validation feature of Bean Validation into a
Spring context through a `MethodValidationPostProcessor` bean definition:
-[tabs]
-======
-Java::
-+
-[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-----
- import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
-
- @Configuration
- public class AppConfig {
-
- @Bean
- public static MethodValidationPostProcessor validationPostProcessor() {
- return new MethodValidationPostProcessor();
- }
- }
-
-----
-
-XML::
-+
-[source,xml,indent=0,subs="verbatim,quotes",role="secondary"]
-----
-
-----
-======
+include-code::./ApplicationConfiguration[tag=snippet,indent=0]
To be eligible for Spring-driven method validation, target classes need to be annotated
with Spring's `@Validated` annotation, which can optionally also declare the validation
@@ -345,36 +320,7 @@ By default, `jakarta.validation.ConstraintViolationException` is raised with the
you can have `MethodValidationException` raised instead with ``ConstraintViolation``s
adapted to `MessageSourceResolvable` errors. To enable set the following flag:
-[tabs]
-======
-Java::
-+
-[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-----
- import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
-
- @Configuration
- public class AppConfig {
-
- @Bean
- public static MethodValidationPostProcessor validationPostProcessor() {
- MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
- processor.setAdaptConstraintViolations(true);
- return processor;
- }
- }
-
-----
-
-XML::
-+
-[source,xml,indent=0,subs="verbatim,quotes",role="secondary"]
-----
-
-
-
-----
-======
+include-code::./ApplicationConfiguration[tag=snippet,indent=0]
`MethodValidationException` contains a list of ``ParameterValidationResult``s which
group errors by method parameter, and each exposes a `MethodParameter`, the argument
diff --git a/framework-docs/src/main/java/org/springframework/docs/core/validation/validationbeanvalidationspringmethod/ApplicationConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/core/validation/validationbeanvalidationspringmethod/ApplicationConfiguration.java
new file mode 100644
index 0000000000..c25e2ab073
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/core/validation/validationbeanvalidationspringmethod/ApplicationConfiguration.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2002-2024 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.docs.core.validation.validationbeanvalidationspringmethod;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
+
+// tag::snippet[]
+@Configuration
+public class ApplicationConfiguration {
+
+ @Bean
+ public static MethodValidationPostProcessor validationPostProcessor() {
+ return new MethodValidationPostProcessor();
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/core/validation/validationbeanvalidationspringmethodexceptions/ApplicationConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/core/validation/validationbeanvalidationspringmethodexceptions/ApplicationConfiguration.java
new file mode 100644
index 0000000000..ad18753eaf
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/core/validation/validationbeanvalidationspringmethodexceptions/ApplicationConfiguration.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2002-2024 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.docs.core.validation.validationbeanvalidationspringmethodexceptions;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
+
+// tag::snippet[]
+@Configuration
+public class ApplicationConfiguration {
+
+ @Bean
+ public static MethodValidationPostProcessor validationPostProcessor() {
+ MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
+ processor.setAdaptConstraintViolations(true);
+ return processor;
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/core/validation/validationbeanvalidationspringmethod/ApplicationConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/core/validation/validationbeanvalidationspringmethod/ApplicationConfiguration.kt
new file mode 100644
index 0000000000..be0946c837
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/core/validation/validationbeanvalidationspringmethod/ApplicationConfiguration.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2002-2024 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.docs.core.validation.validationbeanvalidationspringmethod
+
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.validation.beanvalidation.MethodValidationPostProcessor
+
+// tag::snippet[]
+@Configuration
+class ApplicationConfiguration {
+
+ companion object {
+
+ @Bean
+ @JvmStatic
+ fun validationPostProcessor() = MethodValidationPostProcessor()
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/core/validation/validationbeanvalidationspringmethodexceptions/ApplicationConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/core/validation/validationbeanvalidationspringmethodexceptions/ApplicationConfiguration.kt
new file mode 100644
index 0000000000..07e383481e
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/core/validation/validationbeanvalidationspringmethodexceptions/ApplicationConfiguration.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2002-2024 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.docs.core.validation.validationbeanvalidationspringmethodexceptions
+
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.validation.beanvalidation.MethodValidationPostProcessor
+
+// tag::snippet[]
+@Configuration
+class ApplicationConfiguration {
+
+ companion object {
+
+ @Bean
+ @JvmStatic
+ fun validationPostProcessor() = MethodValidationPostProcessor().apply {
+ setAdaptConstraintViolations(true)
+ }
+ }
+}
+// end::snippet[]
\ No newline at end of file
diff --git a/framework-docs/src/main/resources/org/springframework/docs/core/validation/validationbeanvalidationspringmethod/ApplicationConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/core/validation/validationbeanvalidationspringmethod/ApplicationConfiguration.xml
new file mode 100644
index 0000000000..2d0fc90294
--- /dev/null
+++ b/framework-docs/src/main/resources/org/springframework/docs/core/validation/validationbeanvalidationspringmethod/ApplicationConfiguration.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/framework-docs/src/main/resources/org/springframework/docs/core/validation/validationbeanvalidationspringmethodexceptions/ApplicationConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/core/validation/validationbeanvalidationspringmethodexceptions/ApplicationConfiguration.xml
new file mode 100644
index 0000000000..c7477ce108
--- /dev/null
+++ b/framework-docs/src/main/resources/org/springframework/docs/core/validation/validationbeanvalidationspringmethodexceptions/ApplicationConfiguration.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java
index b4356d8957..cddae13bae 100644
--- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java
+++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java
@@ -360,6 +360,9 @@ class ConfigurationClassParser {
// Process individual @Bean methods
Set beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
+ if (methodMetadata.isAnnotated("kotlin.jvm.JvmStatic") && !methodMetadata.isStatic()) {
+ continue;
+ }
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
diff --git a/spring-context/src/test/kotlin/org/springframework/context/annotation/ConfigurationClassKotlinTests.kt b/spring-context/src/test/kotlin/org/springframework/context/annotation/ConfigurationClassKotlinTests.kt
index a12e9d7479..43158dbd07 100644
--- a/spring-context/src/test/kotlin/org/springframework/context/annotation/ConfigurationClassKotlinTests.kt
+++ b/spring-context/src/test/kotlin/org/springframework/context/annotation/ConfigurationClassKotlinTests.kt
@@ -19,8 +19,10 @@ package org.springframework.context.annotation
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.jupiter.api.Test
+import org.springframework.beans.factory.config.BeanPostProcessor
import org.springframework.beans.factory.getBean
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException
+import org.springframework.beans.factory.support.DefaultListableBeanFactory
/**
* Integration tests for Kotlin configuration classes.
@@ -43,6 +45,16 @@ class ConfigurationClassKotlinTests {
assertThat(context.getBean().foo).isEqualTo(foo)
}
+ @Test
+ fun `Configuration with @JvmStatic registers a single bean`() {
+ val beanFactory = DefaultListableBeanFactory().apply {
+ isAllowBeanDefinitionOverriding = false
+ }
+ val context = AnnotationConfigApplicationContext(beanFactory)
+ context.register(ProcessorConfiguration::class.java)
+ context.refresh()
+ }
+
@Configuration
class FinalConfigurationWithProxy {
@@ -64,6 +76,19 @@ class ConfigurationClassKotlinTests {
fun bar(foo: Foo) = Bar(foo)
}
+ @Configuration
+ open class ProcessorConfiguration {
+
+ companion object {
+
+ @Bean
+ @JvmStatic
+ fun processor(): BeanPostProcessor {
+ return object: BeanPostProcessor{}
+ }
+ }
+ }
+
class Foo
class Bar(val foo: Foo)