Improve target detection for FactoryBeans with generic

Closes gh-28809
This commit is contained in:
Stephane Nicoll
2022-07-22 13:09:10 +02:00
parent bbcc269487
commit c1738aab0d
5 changed files with 136 additions and 13 deletions

View File

@@ -27,6 +27,7 @@ import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.testfixture.beans.factory.DummyFactory;
import org.springframework.beans.testfixture.beans.factory.aot.MockBeanRegistrationsCode;
import org.springframework.core.ResolvableType;
import org.springframework.core.testfixture.aot.generate.TestGenerationContext;
import org.springframework.util.ReflectionUtils;
@@ -57,6 +58,29 @@ class DefaultBeanRegistrationCodeFragmentsTests {
SimpleBeanFactoryBean.class.getDeclaredConstructors()[0])).isEqualTo(SimpleBean.class);
}
@Test
void getTargetOnConstructorToPublicGenericFactoryBeanExtractTargetFromFactoryBeanType() {
RegisteredBean registeredBean = registerTestBean(ResolvableType
.forClassWithGenerics(GenericFactoryBean.class, SimpleBean.class));
assertThat(createInstance(registeredBean).getTarget(registeredBean,
GenericFactoryBean.class.getDeclaredConstructors()[0])).isEqualTo(SimpleBean.class);
}
@Test
void getTargetOnConstructorToPublicGenericFactoryBeanWithBoundExtractTargetFromFactoryBeanType() {
RegisteredBean registeredBean = registerTestBean(ResolvableType
.forClassWithGenerics(NumberFactoryBean.class, Integer.class));
assertThat(createInstance(registeredBean).getTarget(registeredBean,
NumberFactoryBean.class.getDeclaredConstructors()[0])).isEqualTo(Integer.class);
}
@Test
void getTargetOnConstructorToPublicGenericFactoryBeanUseBeanTypeAsFallback() {
RegisteredBean registeredBean = registerTestBean(SimpleBean.class);
assertThat(createInstance(registeredBean).getTarget(registeredBean,
GenericFactoryBean.class.getDeclaredConstructors()[0])).isEqualTo(SimpleBean.class);
}
@Test
void getTargetOnConstructorToProtectedFactoryBean() {
RegisteredBean registeredBean = registerTestBean(SimpleBean.class);
@@ -138,6 +162,12 @@ class DefaultBeanRegistrationCodeFragmentsTests {
return RegisteredBean.of(this.beanFactory, "testBean");
}
private RegisteredBean registerTestBean(ResolvableType beanType) {
this.beanFactory.registerBeanDefinition("testBean",
new RootBeanDefinition(beanType));
return RegisteredBean.of(this.beanFactory, "testBean");
}
private BeanRegistrationCodeFragments createInstance(RegisteredBean registeredBean) {
return new DefaultBeanRegistrationCodeFragments(this.beanRegistrationsCode, registeredBean,
new BeanDefinitionMethodGeneratorFactory(this.beanFactory));