diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java index a05722f24f..bd19259339 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java @@ -21,6 +21,7 @@ import java.util.function.Supplier; import org.springframework.beans.factory.config.AutowiredPropertyMarker; import org.springframework.beans.factory.config.BeanDefinitionCustomizer; import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.core.ResolvableType; import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; @@ -102,7 +103,7 @@ public final class BeanDefinitionBuilder { * @param beanClass the {@code Class} of the bean that the definition is being created for */ public static BeanDefinitionBuilder rootBeanDefinition(Class beanClass) { - return rootBeanDefinition(beanClass, null); + return rootBeanDefinition(beanClass, (String) null); } /** @@ -117,6 +118,30 @@ public final class BeanDefinitionBuilder { return builder; } + /** + * Create a new {@code BeanDefinitionBuilder} used to construct a {@link RootBeanDefinition}. + * @param beanType the {@link ResolvableType type} of the bean that the definition is being created for + * @param instanceSupplier a callback for creating an instance of the bean + * @since 5.3.9 + */ + public static BeanDefinitionBuilder rootBeanDefinition(ResolvableType beanType, Supplier instanceSupplier) { + RootBeanDefinition beanDefinition = new RootBeanDefinition(); + beanDefinition.setTargetType(beanType); + beanDefinition.setInstanceSupplier(instanceSupplier); + return new BeanDefinitionBuilder(beanDefinition); + } + + /** + * Create a new {@code BeanDefinitionBuilder} used to construct a {@link RootBeanDefinition}. + * @param beanClass the {@code Class} of the bean that the definition is being created for + * @param instanceSupplier a callback for creating an instance of the bean + * @since 5.3.9 + * @see #rootBeanDefinition(ResolvableType, Supplier) + */ + public static BeanDefinitionBuilder rootBeanDefinition(Class beanClass, Supplier instanceSupplier) { + return rootBeanDefinition(ResolvableType.forClass(beanClass), instanceSupplier); + } + /** * Create a new {@code BeanDefinitionBuilder} used to construct a {@link ChildBeanDefinition}. * @param parentName the name of the parent bean diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionBuilderTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionBuilderTests.java index 1db78dd8b4..7a6b938ea1 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionBuilderTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionBuilderTests.java @@ -17,11 +17,13 @@ package org.springframework.beans.factory.support; import java.util.Arrays; +import java.util.function.Function; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.testfixture.beans.TestBean; +import org.springframework.core.ResolvableType; import static org.assertj.core.api.Assertions.assertThat; @@ -75,6 +77,26 @@ class BeanDefinitionBuilderTests { assertThat(rbd.getFactoryMethodName()).isEqualTo("create"); } + @Test + void builderWithResolvableTypeAndInstanceSupplier() { + ResolvableType type = ResolvableType.forClassWithGenerics(Function.class, Integer.class, String.class); + Function function = i -> "value " + i; + RootBeanDefinition rbd = (RootBeanDefinition) BeanDefinitionBuilder + .rootBeanDefinition(type, () -> function).getBeanDefinition(); + assertThat(rbd.getResolvableType()).isEqualTo(type); + assertThat(rbd.getInstanceSupplier()).isNotNull(); + assertThat(rbd.getInstanceSupplier().get()).isInstanceOf(Function.class); + } + + @Test + void builderWithBeanClassAndInstanceSupplier() { + RootBeanDefinition rbd = (RootBeanDefinition) BeanDefinitionBuilder + .rootBeanDefinition(String.class, () -> "test").getBeanDefinition(); + assertThat(rbd.getResolvableType().resolve()).isEqualTo(String.class); + assertThat(rbd.getInstanceSupplier()).isNotNull(); + assertThat(rbd.getInstanceSupplier().get()).isEqualTo("test"); + } + @Test void builderWithAutowireMode() { assertThat(BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)