Ignore overridden factory methods for unique candidate resolution

See gh-27920
This commit is contained in:
Juergen Hoeller 2022-10-06 15:06:53 +02:00
parent 455a736a01
commit 6027be5a39
2 changed files with 25 additions and 4 deletions

View File

@ -371,7 +371,7 @@ class ConstructorResolver {
*/ */
private Method[] getCandidateMethods(Class<?> factoryClass, RootBeanDefinition mbd) { private Method[] getCandidateMethods(Class<?> factoryClass, RootBeanDefinition mbd) {
return (mbd.isNonPublicAccessAllowed() ? return (mbd.isNonPublicAccessAllowed() ?
ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods()); ReflectionUtils.getUniqueDeclaredMethods(factoryClass) : factoryClass.getMethods());
} }
private boolean isStaticCandidate(Method method, Class<?> factoryClass) { private boolean isStaticCandidate(Method method, Class<?> factoryClass) {

View File

@ -86,7 +86,7 @@ class ConstructorResolverAotTests {
} }
@Test @Test
void beanDefinitionWithFactoryMethodNameAndMatchingMethodNamesThatShouldBeIgnored() { void beanDefinitionWithFactoryMethodNameAndMatchingMethodNames() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
BeanDefinition beanDefinition = BeanDefinitionBuilder BeanDefinition beanDefinition = BeanDefinitionBuilder
.rootBeanDefinition(DummySampleFactory.class).setFactoryMethod("of") .rootBeanDefinition(DummySampleFactory.class).setFactoryMethod("of")
@ -96,6 +96,18 @@ class ConstructorResolverAotTests {
.findMethod(DummySampleFactory.class, "of", Integer.class)); .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 @Test
void detectBeanInstanceExecutableWithBeanClassAndFactoryMethodNameIgnoreTargetType() { void detectBeanInstanceExecutableWithBeanClassAndFactoryMethodNameIgnoreTargetType() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
@ -386,8 +398,17 @@ class ConstructorResolverAotTests {
return value.toString(); return value.toString();
} }
private String of(String ignored) { protected String resolve(String value) {
return ignored; return value;
}
}
@SuppressWarnings("unused")
static class ExtendedSampleFactory extends DummySampleFactory {
@Override
protected String resolve(String value) {
return super.resolve(value);
} }
} }