Skip to content

Commit 8084da5

Browse files
committed
Map resolution for multiple beans applies to plain Map interface declaration only
Issue: SPR-15117
1 parent 9e6aa0f commit 8084da5

File tree

2 files changed

+146
-4
lines changed

2 files changed

+146
-4
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -1173,7 +1173,7 @@ else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
11731173
}
11741174
return result;
11751175
}
1176-
else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
1176+
else if (Map.class == type) {
11771177
Class<?> keyType = descriptor.getMapKeyType();
11781178
if (String.class != keyType) {
11791179
return null;

spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -929,6 +929,28 @@ public void testConstructorInjectionWithPlainMapAsBean() {
929929
assertSame(bf.getBean("myTestBeanMap"), bean.getTestBeanMap());
930930
}
931931

932+
@Test
933+
public void testConstructorInjectionWithCustomMapAsBean() {
934+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
935+
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
936+
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
937+
bpp.setBeanFactory(bf);
938+
bf.addBeanPostProcessor(bpp);
939+
RootBeanDefinition bd = new RootBeanDefinition(CustomMapConstructorInjectionBean.class);
940+
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
941+
bf.registerBeanDefinition("annotatedBean", bd);
942+
RootBeanDefinition tbm = new RootBeanDefinition(CustomCollectionFactoryMethods.class);
943+
tbm.setUniqueFactoryMethodName("testBeanMap");
944+
bf.registerBeanDefinition("myTestBeanMap", tbm);
945+
bf.registerSingleton("testBean1", new TestBean());
946+
bf.registerSingleton("testBean2", new TestBean());
947+
948+
CustomMapConstructorInjectionBean bean = (CustomMapConstructorInjectionBean) bf.getBean("annotatedBean");
949+
assertSame(bf.getBean("myTestBeanMap"), bean.getTestBeanMap());
950+
bean = (CustomMapConstructorInjectionBean) bf.getBean("annotatedBean");
951+
assertSame(bf.getBean("myTestBeanMap"), bean.getTestBeanMap());
952+
}
953+
932954
@Test
933955
public void testConstructorInjectionWithTypedSetAsBean() {
934956
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@@ -972,6 +994,26 @@ public void testConstructorInjectionWithPlainSetAsBean() {
972994
assertSame(bf.getBean("myTestBeanSet"), bean.getTestBeanSet());
973995
}
974996

997+
@Test
998+
public void testConstructorInjectionWithCustomSetAsBean() {
999+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1000+
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1001+
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1002+
bpp.setBeanFactory(bf);
1003+
bf.addBeanPostProcessor(bpp);
1004+
RootBeanDefinition bd = new RootBeanDefinition(CustomSetConstructorInjectionBean.class);
1005+
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1006+
bf.registerBeanDefinition("annotatedBean", bd);
1007+
RootBeanDefinition tbs = new RootBeanDefinition(CustomCollectionFactoryMethods.class);
1008+
tbs.setUniqueFactoryMethodName("testBeanSet");
1009+
bf.registerBeanDefinition("myTestBeanSet", tbs);
1010+
1011+
CustomSetConstructorInjectionBean bean = (CustomSetConstructorInjectionBean) bf.getBean("annotatedBean");
1012+
assertSame(bf.getBean("myTestBeanSet"), bean.getTestBeanSet());
1013+
bean = (CustomSetConstructorInjectionBean) bf.getBean("annotatedBean");
1014+
assertSame(bf.getBean("myTestBeanSet"), bean.getTestBeanSet());
1015+
}
1016+
9751017
@Test
9761018
public void testSelfReference() {
9771019
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@@ -2195,6 +2237,18 @@ public void testAnnotatedDefaultConstructor() {
21952237
assertNotNull(bf.getBean("annotatedBean"));
21962238
}
21972239

2240+
@Test @Ignore // SPR-15125
2241+
public void testFactoryBeanSelfInjection() {
2242+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
2243+
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
2244+
bpp.setBeanFactory(bf);
2245+
bf.addBeanPostProcessor(bpp);
2246+
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(SelfInjectingFactoryBean.class));
2247+
2248+
SelfInjectingFactoryBean bean = bf.getBean(SelfInjectingFactoryBean.class);
2249+
assertSame(bf.getBean("annotatedBean"), bean.testBean);
2250+
}
2251+
21982252

21992253
@Qualifier("integerRepo")
22002254
private Repository<?> integerRepositoryQualifierProvider;
@@ -3251,7 +3305,7 @@ public static class StringGenericInterface1Impl extends GenericInterface1Impl<St
32513305

32523306
public interface GenericInterface2<K> {
32533307

3254-
public String doSomethingMoreGeneric(K o);
3308+
String doSomethingMoreGeneric(K o);
32553309
}
32563310

32573311

@@ -3437,11 +3491,99 @@ public static Set<TestBean> testBeanSet() {
34373491
}
34383492

34393493

3494+
public static class CustomCollectionFactoryMethods {
3495+
3496+
public static CustomMap<String, TestBean> testBeanMap() {
3497+
CustomMap<String, TestBean> tbm = new CustomHashMap<>();
3498+
tbm.put("testBean1", new TestBean("tb1"));
3499+
tbm.put("testBean2", new TestBean("tb2"));
3500+
return tbm;
3501+
}
3502+
3503+
public static CustomSet<TestBean> testBeanSet() {
3504+
CustomSet<TestBean> tbs = new CustomHashSet<>();
3505+
tbs.add(new TestBean("tb1"));
3506+
tbs.add(new TestBean("tb2"));
3507+
return tbs;
3508+
}
3509+
}
3510+
3511+
3512+
public static class CustomMapConstructorInjectionBean {
3513+
3514+
private CustomMap<String, TestBean> testBeanMap;
3515+
3516+
@Autowired
3517+
public CustomMapConstructorInjectionBean(CustomMap<String, TestBean> testBeanMap) {
3518+
this.testBeanMap = testBeanMap;
3519+
}
3520+
3521+
public CustomMap<String, TestBean> getTestBeanMap() {
3522+
return this.testBeanMap;
3523+
}
3524+
}
3525+
3526+
3527+
public static class CustomSetConstructorInjectionBean {
3528+
3529+
private CustomSet<TestBean> testBeanSet;
3530+
3531+
@Autowired
3532+
public CustomSetConstructorInjectionBean(CustomSet<TestBean> testBeanSet) {
3533+
this.testBeanSet = testBeanSet;
3534+
}
3535+
3536+
public CustomSet<TestBean> getTestBeanSet() {
3537+
return this.testBeanSet;
3538+
}
3539+
}
3540+
3541+
3542+
public interface CustomMap<K, V> extends Map<K, V> {
3543+
}
3544+
3545+
3546+
public static class CustomHashMap<K, V> extends LinkedHashMap<K, V> implements CustomMap<K, V> {
3547+
}
3548+
3549+
3550+
public interface CustomSet<E> extends Set<E> {
3551+
}
3552+
3553+
3554+
public static class CustomHashSet<E> extends LinkedHashSet<E> implements CustomSet<E> {
3555+
}
3556+
3557+
34403558
public static class AnnotatedDefaultConstructorBean {
34413559

34423560
@Autowired
34433561
public AnnotatedDefaultConstructorBean() {
34443562
}
34453563
}
34463564

3565+
3566+
public static class SelfInjectingFactoryBean implements FactoryBean<TestBean> {
3567+
3568+
private final TestBean exposedTestBean = new TestBean();
3569+
3570+
@Autowired
3571+
TestBean testBean;
3572+
3573+
@Override
3574+
public TestBean getObject() {
3575+
return exposedTestBean;
3576+
}
3577+
3578+
@Override
3579+
public Class<?> getObjectType() {
3580+
return TestBean.class;
3581+
}
3582+
3583+
@Override
3584+
public boolean isSingleton() {
3585+
return true;
3586+
}
3587+
}
3588+
34473589
}

0 commit comments

Comments
 (0)