Skip to content

Commit 52d124d

Browse files
committed
Use supplier-aligned type information for FactoryBean type resolution
Issue: SPR-17063
1 parent 0b60447 commit 52d124d

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,22 @@ protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition m
796796
@Override
797797
@Nullable
798798
protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
799+
if (mbd.getInstanceSupplier() != null) {
800+
ResolvableType targetType = mbd.targetType;
801+
if (targetType != null) {
802+
Class<?> result = targetType.as(FactoryBean.class).getGeneric().resolve();
803+
if (result != null) {
804+
return result;
805+
}
806+
}
807+
if (mbd.hasBeanClass()) {
808+
Class<?> result = GenericTypeResolver.resolveTypeArgument(mbd.getBeanClass(), FactoryBean.class);
809+
if (result != null) {
810+
return result;
811+
}
812+
}
813+
}
814+
799815
String factoryBeanName = mbd.getFactoryBeanName();
800816
String factoryMethodName = mbd.getFactoryMethodName();
801817

spring-context/src/test/java/org/springframework/context/annotation/AnnotationConfigApplicationContextTests.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
2626
import org.springframework.beans.factory.annotation.Autowired;
2727
import org.springframework.beans.factory.config.BeanPostProcessor;
28+
import org.springframework.beans.factory.support.RootBeanDefinition;
2829
import org.springframework.context.ApplicationContext;
2930
import org.springframework.context.annotation6.ComponentForScanning;
3031
import org.springframework.context.annotation6.ConfigForScanning;
3132
import org.springframework.context.annotation6.Jsr330NamedForScanning;
33+
import org.springframework.core.ResolvableType;
3234
import org.springframework.util.ObjectUtils;
3335

3436
import static java.lang.String.*;
@@ -279,6 +281,30 @@ public void individualNamedBeanWithMixedConstructorArguments() {
279281
assertSame(context, context.getBean("b", BeanB.class).applicationContext);
280282
}
281283

284+
@Test
285+
public void individualBeanWithFactoryBeanSupplier() {
286+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
287+
context.registerBean("fb", TypedFactoryBean.class, TypedFactoryBean::new, bd -> bd.setLazyInit(true));
288+
context.refresh();
289+
290+
assertEquals(String.class, context.getType("fb"));
291+
assertEquals(TypedFactoryBean.class, context.getType("&fb"));
292+
}
293+
294+
@Test
295+
public void individualBeanWithFactoryBeanSupplierAndTargetType() {
296+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
297+
RootBeanDefinition bd = new RootBeanDefinition();
298+
bd.setInstanceSupplier(TypedFactoryBean::new);
299+
bd.setTargetType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class));
300+
bd.setLazyInit(true);
301+
context.registerBeanDefinition("fb", bd);
302+
context.refresh();
303+
304+
assertEquals(String.class, context.getType("fb"));
305+
assertEquals(FactoryBean.class, context.getType("&fb"));
306+
}
307+
282308
@Test
283309
public void getBeanByTypeRaisesNoSuchBeanDefinitionException() {
284310
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
@@ -428,6 +454,28 @@ public BeanB() {
428454

429455
static class BeanC {}
430456

457+
static class TypedFactoryBean implements FactoryBean<String> {
458+
459+
public TypedFactoryBean() {
460+
throw new IllegalStateException();
461+
}
462+
463+
@Override
464+
public String getObject() {
465+
return "";
466+
}
467+
468+
@Override
469+
public Class<?> getObjectType() {
470+
return String.class;
471+
}
472+
473+
@Override
474+
public boolean isSingleton() {
475+
return true;
476+
}
477+
}
478+
431479
static class UntypedFactoryBean implements FactoryBean<Object> {
432480

433481
@Override

0 commit comments

Comments
 (0)