Revisit GenericApplicationContext.registerBean constructor handling

Support for Kotlin primary constructor and non-default public constructors in addition to default instantiation, aligned with AnnotationConfigApplicationContext and model attribute processing.

Issue: SPR-17292
This commit is contained in:
Juergen Hoeller
2018-09-19 22:19:43 +02:00
parent 50c9542796
commit d3c08552e9
5 changed files with 279 additions and 91 deletions

View File

@@ -1146,7 +1146,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
}
// Need to determine the constructor...
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
@@ -1154,6 +1154,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}

View File

@@ -17,6 +17,7 @@
package org.springframework.beans.factory.support;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
@@ -335,6 +336,18 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
return (targetType != null ? targetType : ResolvableType.forClass(getBeanClass()));
}
/**
* Determine preferred constructors to use for default construction, if any.
* Constructor arguments will be autowired if necessary.
* @return one or more preferred constructors, or {@code null} if none
* (in which case the regular no-arg default constructor will be called)
* @since 5.1
*/
@Nullable
public Constructor<?>[] getPreferredConstructors() {
return null;
}
/**
* Specify a factory method name that refers to a non-overloaded method.
*/