Ignore InstanceSupplier for getBean with arguments

Previously, a BeanDefinition that has an instance supplier would be
used irrespective of custom arguments being provided. This commit only
applies the instance supplier if no arguments are provided. With
custom arguments, the regular lookup takes place based on the
information provided in the bean factory.

Closes gh-32657
This commit is contained in:
Stéphane Nicoll 2024-04-22 16:59:31 +02:00
parent 8a8c8fe00e
commit c99e7f8616
2 changed files with 45 additions and 3 deletions

View File

@ -1156,9 +1156,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName, mbd);
if (args == null) {
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName, mbd);
}
}
if (mbd.getFactoryMethodName() != null) {

View File

@ -1967,6 +1967,42 @@ class DefaultListableBeanFactoryTests {
lbf.getBean(TestBean.class, 67));
}
@Test
void getBeanByTypeInstanceWithConstructorIgnoresInstanceSupplier() {
RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99);
bd1.setInstanceSupplier(() -> new ConstructorDependency(new TestBean("test")));
lbf.registerBeanDefinition("bd1", bd1);
ConstructorDependency defaultInstance = lbf.getBean(ConstructorDependency.class);
assertThat(defaultInstance.beanName).isEqualTo("bd1");
assertThat(defaultInstance.spouseAge).isEqualTo(0);
ConstructorDependency argsInstance = lbf.getBean(ConstructorDependency.class, 42);
assertThat(argsInstance.beanName).isEqualTo("bd1");
assertThat(argsInstance.spouseAge).isEqualTo(42);
}
@Test
void getBeanByTypeInstanceWithFactoryMethodIgnoresInstanceSupplier() {
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
bd1.setScope(BeanDefinition.SCOPE_PROTOTYPE);
bd1.setFactoryBeanName("config");
bd1.setFactoryMethodName("create");
bd1.setInstanceSupplier(() -> new TestBean("test"));
lbf.registerBeanDefinition("config", new RootBeanDefinition(BeanWithFactoryMethod.class));
lbf.registerBeanDefinition("bd1", bd1);
TestBean defaultInstance = lbf.getBean(TestBean.class);
assertThat(defaultInstance.getBeanName()).isEqualTo("bd1");
assertThat(defaultInstance.getName()).isEqualTo("test");
assertThat(defaultInstance.getAge()).isEqualTo(0);
TestBean argsInstance = lbf.getBean(TestBean.class, "another", 42);
assertThat(argsInstance.getBeanName()).isEqualTo("bd1");
assertThat(argsInstance.getName()).isEqualTo("another");
assertThat(argsInstance.getAge()).isEqualTo(42);
}
@Test
@SuppressWarnings("rawtypes")
void beanProviderSerialization() throws Exception {
@ -3173,6 +3209,10 @@ class DefaultListableBeanFactoryTests {
return tb;
}
public TestBean create(String name, int age) {
return new TestBean(name, age);
}
public TestBean createWithArgs(String arg) {
TestBean tb = new TestBean();
tb.setName(arg);