Merge AOT constructor and factory method resolution into ConstructorResolver

This moves related code into the same class, unifies candidate determination for constructors and factory methods, and gets rid of the package cycle around the hard-coded Autowired annotation check (which is implicitly coming from AutowiredAnnotationBeanPostProcessor via the determineCandidateConstructors SPI now). The API entry point for AOT pre-resolution purposes is in RegisteredBean.

Closes gh-27920
This commit is contained in:
Juergen Hoeller
2022-10-06 11:59:11 +02:00
parent 3af0c232b7
commit aedef9321a
7 changed files with 377 additions and 468 deletions

View File

@@ -294,9 +294,9 @@ class InstanceSupplierCodeGeneratorTests {
return (T) beanFactory.getBean("testBean");
}
private void compile(DefaultListableBeanFactory beanFactory,
BeanDefinition beanDefinition,
private void compile(DefaultListableBeanFactory beanFactory, BeanDefinition beanDefinition,
BiConsumer<InstanceSupplier<?>, Compiled> result) {
DefaultListableBeanFactory freshBeanFactory = new DefaultListableBeanFactory(beanFactory);
freshBeanFactory.registerBeanDefinition("testBean", beanDefinition);
RegisteredBean registeredBean = RegisteredBean.of(freshBeanFactory, "testBean");
@@ -305,7 +305,7 @@ class InstanceSupplierCodeGeneratorTests {
InstanceSupplierCodeGenerator generator = new InstanceSupplierCodeGenerator(
this.generationContext, generateClass.getName(),
generateClass.getMethods(), false);
Executable constructorOrFactoryMethod = ConstructorOrFactoryMethodResolver.resolve(registeredBean);
Executable constructorOrFactoryMethod = registeredBean.resolveConstructorOrFactoryMethod();
assertThat(constructorOrFactoryMethod).isNotNull();
CodeBlock generatedCode = generator.generateCode(registeredBean, constructorOrFactoryMethod);
typeBuilder.set(type -> {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.beans.factory.aot;
package org.springframework.beans.factory.support;
import java.lang.annotation.Annotation;
import java.lang.reflect.Executable;
@@ -26,9 +26,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.testfixture.beans.factory.generator.factory.NumberHolder;
import org.springframework.beans.testfixture.beans.factory.generator.factory.NumberHolderFactoryBean;
import org.springframework.beans.testfixture.beans.factory.generator.factory.SampleFactory;
@@ -41,12 +38,12 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Tests for {@link ConstructorOrFactoryMethodResolver}.
* Tests for AOT constructor and factory method resolution.
*
* @author Stephane Nicoll
* @author Phillip Webb
*/
class ConstructorOrFactoryMethodResolverTests {
class ConstructorAndFactoryMethodResolutionTests {
@Test
void detectBeanInstanceExecutableWithBeanClassAndFactoryMethodName() {
@@ -125,21 +122,6 @@ class ConstructorOrFactoryMethodResolverTests {
.getDeclaredConstructor(Number.class, String.class));
}
@Test
void genericBeanDefinitionWithConstructorArgsForMultipleConstructors()
throws Exception {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("testNumber", 1L);
beanFactory.registerSingleton("testBean", "test");
BeanDefinition beanDefinition = BeanDefinitionBuilder
.genericBeanDefinition(SampleBeanWithConstructors.class)
.addConstructorArgReference("testNumber")
.addConstructorArgReference("testBean").getBeanDefinition();
Executable executable = resolve(beanFactory, beanDefinition);
assertThat(executable).isNotNull().isEqualTo(SampleBeanWithConstructors.class
.getDeclaredConstructor(Number.class, String.class));
}
@Test
void beanDefinitionWithMultiArgConstructorAndMatchingValue() throws NoSuchMethodException {
BeanDefinition beanDefinition = BeanDefinitionBuilder
@@ -341,7 +323,8 @@ class ConstructorOrFactoryMethodResolverTests {
private Executable resolve(DefaultListableBeanFactory beanFactory, BeanDefinition beanDefinition) {
return new ConstructorOrFactoryMethodResolver(beanFactory).resolve(beanDefinition);
return new ConstructorResolver(beanFactory).resolveConstructorOrFactoryMethod(
"testBean", (RootBeanDefinition) beanDefinition);
}