|
32 | 32 | import org.mockito.Mockito;
|
33 | 33 |
|
34 | 34 | import org.springframework.beans.factory.BeanCreationException;
|
| 35 | +import org.springframework.beans.factory.FactoryBean; |
35 | 36 | import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
36 | 37 | import org.springframework.beans.factory.ObjectProvider;
|
37 | 38 | import org.springframework.beans.factory.config.TypedStringValue;
|
@@ -850,6 +851,23 @@ void genericMatchingWithUnresolvedOrderedStream() {
|
850 | 851 | bf.getBean("store2", NumberStore.class), bf.getBean("store1", NumberStore.class));
|
851 | 852 | }
|
852 | 853 |
|
| 854 | + @Test // gh-32489 |
| 855 | + void genericMatchingAgainstFactoryBeanClass() { |
| 856 | + DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); |
| 857 | + bf.setAutowireCandidateResolver(new GenericTypeAwareAutowireCandidateResolver()); |
| 858 | + |
| 859 | + RootBeanDefinition bd = new RootBeanDefinition(MyFactoryBean.class); |
| 860 | + // Replicate org.springframework.data.repository.config.RepositoryConfigurationDelegate#registerRepositoriesIn |
| 861 | + // behavior of setting targetType, required to hit other branch in |
| 862 | + // org.springframework.beans.factory.support.GenericTypeAwareAutowireCandidateResolver.checkGenericTypeMatch |
| 863 | + bd.setTargetType(ResolvableType.forClassWithGenerics(MyFactoryBean.class, String.class)); |
| 864 | + bf.registerBeanDefinition("myFactoryBean", bd); |
| 865 | + bf.registerBeanDefinition("myFactoryBeanHolder", |
| 866 | + new RootBeanDefinition(MyFactoryBeanHolder.class, AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR, false)); |
| 867 | + |
| 868 | + assertThat(bf.getBean(MyFactoryBeanHolder.class).factoryBeans).contains(bf.getBean(MyFactoryBean.class)); |
| 869 | + } |
| 870 | + |
853 | 871 |
|
854 | 872 | /**
|
855 | 873 | * Mimics and delegates to {@link Mockito#mock(Class)} -- created here to avoid factory
|
@@ -966,4 +984,32 @@ public static NumberStore<Float> newFloatStore() {
|
966 | 984 | }
|
967 | 985 | }
|
968 | 986 |
|
| 987 | + |
| 988 | + public interface MyGenericInterfaceForFactoryBeans<T> { |
| 989 | + } |
| 990 | + |
| 991 | + |
| 992 | + public static class MyFactoryBean<T extends CharSequence> implements FactoryBean<T>, MyGenericInterfaceForFactoryBeans<T> { |
| 993 | + |
| 994 | + @Override |
| 995 | + public T getObject() { |
| 996 | + throw new UnsupportedOperationException(); |
| 997 | + } |
| 998 | + |
| 999 | + @Override |
| 1000 | + public Class<?> getObjectType() { |
| 1001 | + return String.class; |
| 1002 | + } |
| 1003 | + } |
| 1004 | + |
| 1005 | + |
| 1006 | + public static class MyFactoryBeanHolder { |
| 1007 | + |
| 1008 | + List<MyGenericInterfaceForFactoryBeans<?>> factoryBeans; // Requested type is not a FactoryBean type |
| 1009 | + |
| 1010 | + public MyFactoryBeanHolder(List<MyGenericInterfaceForFactoryBeans<?>> factoryBeans) { |
| 1011 | + this.factoryBeans = factoryBeans; |
| 1012 | + } |
| 1013 | + } |
| 1014 | + |
969 | 1015 | }
|
0 commit comments