From 6027be5a39a451249d0c68e0f77b5e2576fb3c4f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 6 Oct 2022 15:06:53 +0200 Subject: [PATCH] Ignore overridden factory methods for unique candidate resolution See gh-27920 --- .../factory/support/ConstructorResolver.java | 2 +- .../support/ConstructorResolverAotTests.java | 27 ++++++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java index 5ce9f3f71fc..4985d0bc5be 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java @@ -371,7 +371,7 @@ class ConstructorResolver { */ private Method[] getCandidateMethods(Class factoryClass, RootBeanDefinition mbd) { return (mbd.isNonPublicAccessAllowed() ? - ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods()); + ReflectionUtils.getUniqueDeclaredMethods(factoryClass) : factoryClass.getMethods()); } private boolean isStaticCandidate(Method method, Class factoryClass) { diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/ConstructorResolverAotTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/ConstructorResolverAotTests.java index f03efd2f9b5..da6b27d3609 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/ConstructorResolverAotTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/support/ConstructorResolverAotTests.java @@ -86,7 +86,7 @@ class ConstructorResolverAotTests { } @Test - void beanDefinitionWithFactoryMethodNameAndMatchingMethodNamesThatShouldBeIgnored() { + void beanDefinitionWithFactoryMethodNameAndMatchingMethodNames() { DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); BeanDefinition beanDefinition = BeanDefinitionBuilder .rootBeanDefinition(DummySampleFactory.class).setFactoryMethod("of") @@ -96,6 +96,18 @@ class ConstructorResolverAotTests { .findMethod(DummySampleFactory.class, "of", Integer.class)); } + @Test + void beanDefinitionWithFactoryMethodNameAndOverriddenMethod() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerBeanDefinition("config", new RootBeanDefinition(ExtendedSampleFactory.class)); + BeanDefinition beanDefinition = BeanDefinitionBuilder + .rootBeanDefinition(String.class).setFactoryMethodOnBean("resolve", "config") + .addConstructorArgValue("test").getBeanDefinition(); + Executable executable = resolve(beanFactory, beanDefinition); + assertThat(executable).isNotNull().isEqualTo(ReflectionUtils + .findMethod(ExtendedSampleFactory.class, "resolve", String.class)); + } + @Test void detectBeanInstanceExecutableWithBeanClassAndFactoryMethodNameIgnoreTargetType() { DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); @@ -386,8 +398,17 @@ class ConstructorResolverAotTests { return value.toString(); } - private String of(String ignored) { - return ignored; + protected String resolve(String value) { + return value; + } + } + + @SuppressWarnings("unused") + static class ExtendedSampleFactory extends DummySampleFactory { + + @Override + protected String resolve(String value) { + return super.resolve(value); } }