From c99e7f8616123597c4a171ade1af2976e73f5b74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Mon, 22 Apr 2024 16:59:31 +0200 Subject: [PATCH] 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 --- .../AbstractAutowireCapableBeanFactory.java | 8 ++-- .../DefaultListableBeanFactoryTests.java | 40 +++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 3a2eebb31d..bd7e961326 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -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) { diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java index ee7dfcd45a..3f350cdbb0 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java @@ -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);