Add support for Kotlin BeanPostProcessor beans

This commit adds support for Kotlin BeanPostProcessor beans which should
be defined in a companion object and annotated with `@JvmStatic`.

Closes gh-32946
This commit is contained in:
Sébastien Deleuze
2024-06-06 19:23:25 +02:00
parent 0758ae5ead
commit 7b9cbd7876
9 changed files with 190 additions and 56 deletions

View File

@@ -360,6 +360,9 @@ class ConfigurationClassParser {
// Process individual @Bean methods
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
if (methodMetadata.isAnnotated("kotlin.jvm.JvmStatic") && !methodMetadata.isStatic()) {
continue;
}
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}

View File

@@ -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<Bar>().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)