From 2ee4c3a3631aadc452a52c3423ff48959c0ba3ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Sun, 5 Apr 2026 18:43:47 +0200 Subject: [PATCH] Provide bean conditional registration capabilities in BeanRegistrarDsl Closes gh-36601 --- .../beans/factory/BeanRegistrarDsl.kt | 24 ++++++++++++++++++- .../BeanRegistrarDslConfigurationTests.kt | 20 ++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/spring-beans/src/main/kotlin/org/springframework/beans/factory/BeanRegistrarDsl.kt b/spring-beans/src/main/kotlin/org/springframework/beans/factory/BeanRegistrarDsl.kt index aeb68a5be71..f9eb6242d04 100644 --- a/spring-beans/src/main/kotlin/org/springframework/beans/factory/BeanRegistrarDsl.kt +++ b/spring-beans/src/main/kotlin/org/springframework/beans/factory/BeanRegistrarDsl.kt @@ -18,8 +18,8 @@ package org.springframework.beans.factory import org.springframework.beans.factory.BeanRegistry.SupplierContext import org.springframework.core.ParameterizedTypeReference -import org.springframework.core.ResolvableType import org.springframework.core.env.Environment +import kotlin.reflect.KClass /** * Contract for registering programmatically beans. @@ -364,6 +364,28 @@ open class BeanRegistrarDsl(private val init: BeanRegistrarDsl.() -> Unit): Bean return registry.registerBean(object: ParameterizedTypeReference() {}, customizer) } + /** + * Determine whether a bean of the given name is already registered. + * @param name the name of the bean + * @since 7.1 + */ + fun containsBean(name: String): Boolean = registry.containsBean(name) + + /** + * Determine whether a bean of the given type is already registered. + * @param beanType the type of the bean + * @since 7.1 + */ + fun containsBean(beanType: KClass<*>): Boolean = registry.containsBean(beanType.java) + + /** + * Determine whether a bean of the given type is already registered. + * @param T the type of the bean + * @since 7.1 + */ + inline fun containsBean(): Boolean = + registry.containsBean(object: ParameterizedTypeReference() {}) + /** * Context available from the bean instance supplier designed to give access diff --git a/spring-context/src/test/kotlin/org/springframework/context/annotation/BeanRegistrarDslConfigurationTests.kt b/spring-context/src/test/kotlin/org/springframework/context/annotation/BeanRegistrarDslConfigurationTests.kt index 120e2c229ed..f00ec534562 100644 --- a/spring-context/src/test/kotlin/org/springframework/context/annotation/BeanRegistrarDslConfigurationTests.kt +++ b/spring-context/src/test/kotlin/org/springframework/context/annotation/BeanRegistrarDslConfigurationTests.kt @@ -84,7 +84,13 @@ class BeanRegistrarDslConfigurationTests { assertThat(context.getBeanProvider().singleOrNull()).isNotNull } + @Test + fun containsBean() { + AnnotationConfigApplicationContext(ContainsBeanRegistrarKotlinConfiguration::class.java) + } + class Foo + data class Bar(val foo: Foo) data class Baz(val message: String = "") class Init : InitializingBean { @@ -145,4 +151,18 @@ class BeanRegistrarDslConfigurationTests { private class ChainedBeanRegistrar : BeanRegistrarDsl({ register(SampleBeanRegistrar()) }) + + @Configuration + @Import(ContainsBeanRegistrar::class) + internal class ContainsBeanRegistrarKotlinConfiguration + + private class ContainsBeanRegistrar : BeanRegistrarDsl({ + assertThat(containsBean("foo")).isFalse() + assertThat(containsBean(Foo::class)).isFalse() + assertThat(containsBean()).isFalse() + registerBean("foo") + assertThat(containsBean("foo")).isTrue() + assertThat(containsBean(Foo::class)).isTrue() + assertThat(containsBean()).isTrue() + }) }