Consistent ordered list access and lazy streaming for ObjectProvider
Includes fallback match for collection/map dependency if qualified. Issue: SPR-17272 Issue: SPR-17197
This commit is contained in:
@@ -71,6 +71,7 @@ import org.springframework.tests.sample.beans.NestedTestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.SerializationTestUtils;
|
||||
import org.springframework.util.comparator.Comparators;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@@ -978,6 +979,19 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertSame(bf.getBean("myTestBeanMap"), bean.getTestBeanMap());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructorInjectionWithPlainHashMapAsBean() {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(QualifiedMapConstructorInjectionBean.class);
|
||||
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
|
||||
bf.registerBeanDefinition("annotatedBean", bd);
|
||||
bf.registerBeanDefinition("myTestBeanMap", new RootBeanDefinition(HashMap.class));
|
||||
|
||||
QualifiedMapConstructorInjectionBean bean = (QualifiedMapConstructorInjectionBean) bf.getBean("annotatedBean");
|
||||
assertSame(bf.getBean("myTestBeanMap"), bean.getTestBeanMap());
|
||||
bean = (QualifiedMapConstructorInjectionBean) bf.getBean("annotatedBean");
|
||||
assertSame(bf.getBean("myTestBeanMap"), bean.getTestBeanMap());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructorInjectionWithTypedSetAsBean() {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(SetConstructorInjectionBean.class);
|
||||
@@ -1162,6 +1176,9 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
testBeans = bean.streamTestBeans();
|
||||
assertEquals(1, testBeans.size());
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean")));
|
||||
testBeans = bean.sortedTestBeans();
|
||||
assertEquals(1, testBeans.size());
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1187,6 +1204,9 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
testBeans = bean.streamTestBeans();
|
||||
assertEquals(1, testBeans.size());
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean")));
|
||||
testBeans = bean.sortedTestBeans();
|
||||
assertEquals(1, testBeans.size());
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1214,6 +1234,8 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertTrue(testBeans.isEmpty());
|
||||
testBeans = bean.streamTestBeans();
|
||||
assertTrue(testBeans.isEmpty());
|
||||
testBeans = bean.sortedTestBeans();
|
||||
assertTrue(testBeans.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1249,25 +1271,33 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
List<?> testBeans = bean.iterateTestBeans();
|
||||
assertEquals(2, testBeans.size());
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean1")));
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean2")));
|
||||
assertSame(bf.getBean("testBean1"), testBeans.get(0));
|
||||
assertSame(bf.getBean("testBean2"), testBeans.get(1));
|
||||
testBeans = bean.forEachTestBeans();
|
||||
assertEquals(2, testBeans.size());
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean1")));
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean2")));
|
||||
assertSame(bf.getBean("testBean1"), testBeans.get(0));
|
||||
assertSame(bf.getBean("testBean2"), testBeans.get(1));
|
||||
testBeans = bean.streamTestBeans();
|
||||
assertEquals(2, testBeans.size());
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean1")));
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean2")));
|
||||
assertSame(bf.getBean("testBean1"), testBeans.get(0));
|
||||
assertSame(bf.getBean("testBean2"), testBeans.get(1));
|
||||
testBeans = bean.sortedTestBeans();
|
||||
assertEquals(2, testBeans.size());
|
||||
assertSame(bf.getBean("testBean1"), testBeans.get(0));
|
||||
assertSame(bf.getBean("testBean2"), testBeans.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObjectProviderInjectionWithTargetPrimary() {
|
||||
bf.setDependencyComparator(Comparators.comparable());
|
||||
|
||||
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ObjectProviderInjectionBean.class));
|
||||
RootBeanDefinition tb1 = new RootBeanDefinition(TestBean.class);
|
||||
tb1.getPropertyValues().add("name", "yours");
|
||||
tb1.setPrimary(true);
|
||||
bf.registerBeanDefinition("testBean1", tb1);
|
||||
RootBeanDefinition tb2 = new RootBeanDefinition(TestBean.class);
|
||||
tb2.getPropertyValues().add("name", "mine");
|
||||
tb2.setLazyInit(true);
|
||||
bf.registerBeanDefinition("testBean2", tb2);
|
||||
|
||||
@@ -1281,16 +1311,20 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
List<?> testBeans = bean.iterateTestBeans();
|
||||
assertEquals(2, testBeans.size());
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean1")));
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean2")));
|
||||
assertSame(bf.getBean("testBean1"), testBeans.get(0));
|
||||
assertSame(bf.getBean("testBean2"), testBeans.get(1));
|
||||
testBeans = bean.forEachTestBeans();
|
||||
assertEquals(2, testBeans.size());
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean1")));
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean2")));
|
||||
assertSame(bf.getBean("testBean1"), testBeans.get(0));
|
||||
assertSame(bf.getBean("testBean2"), testBeans.get(1));
|
||||
testBeans = bean.streamTestBeans();
|
||||
assertEquals(2, testBeans.size());
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean1")));
|
||||
assertTrue(testBeans.contains(bf.getBean("testBean2")));
|
||||
assertSame(bf.getBean("testBean1"), testBeans.get(0));
|
||||
assertSame(bf.getBean("testBean2"), testBeans.get(1));
|
||||
testBeans = bean.sortedTestBeans();
|
||||
assertEquals(2, testBeans.size());
|
||||
assertSame(bf.getBean("testBean1"), testBeans.get(1));
|
||||
assertSame(bf.getBean("testBean2"), testBeans.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2668,6 +2702,21 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
|
||||
public static class QualifiedMapConstructorInjectionBean {
|
||||
|
||||
private Map<String, TestBean> testBeanMap;
|
||||
|
||||
@Autowired
|
||||
public QualifiedMapConstructorInjectionBean(@Qualifier("myTestBeanMap") Map<String, TestBean> testBeanMap) {
|
||||
this.testBeanMap = testBeanMap;
|
||||
}
|
||||
|
||||
public Map<String, TestBean> getTestBeanMap() {
|
||||
return this.testBeanMap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class SetConstructorInjectionBean {
|
||||
|
||||
private Set<TestBean> testBeanSet;
|
||||
@@ -2834,6 +2883,10 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
public List<TestBean> streamTestBeans() {
|
||||
return this.testBeanProvider.stream().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<TestBean> sortedTestBeans() {
|
||||
return this.testBeanProvider.toList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ import org.springframework.tests.sample.beans.GenericBean;
|
||||
import org.springframework.tests.sample.beans.GenericIntegerBean;
|
||||
import org.springframework.tests.sample.beans.GenericSetOfIntegerBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.util.comparator.Comparators;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@@ -134,7 +135,7 @@ public class BeanFactoryGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericListPropertyWithOptionalAutowiring() throws MalformedURLException {
|
||||
public void testGenericListPropertyWithOptionalAutowiring() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
|
||||
@@ -846,6 +847,7 @@ public class BeanFactoryGenericsTests {
|
||||
public void testGenericMatchingWithFullTypeDifferentiation() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
bf.setAutowireCandidateResolver(new GenericTypeAwareAutowireCandidateResolver());
|
||||
bf.setDependencyComparator(Comparators.comparable());
|
||||
|
||||
bf.registerBeanDefinition("store1", new RootBeanDefinition(DoubleStore.class));
|
||||
bf.registerBeanDefinition("store2", new RootBeanDefinition(FloatStore.class));
|
||||
@@ -892,38 +894,51 @@ public class BeanFactoryGenericsTests {
|
||||
assertSame(bf.getBean("store2"), floatStoreProvider.getIfAvailable());
|
||||
assertSame(bf.getBean("store2"), floatStoreProvider.getIfUnique());
|
||||
|
||||
Set<Object> resolved = new HashSet<>();
|
||||
List<NumberStore<?>> resolved = new ArrayList<>();
|
||||
for (NumberStore<?> instance : numberStoreProvider) {
|
||||
resolved.add(instance);
|
||||
}
|
||||
assertEquals(2, resolved.size());
|
||||
assertTrue(resolved.contains(bf.getBean("store1")));
|
||||
assertTrue(resolved.contains(bf.getBean("store2")));
|
||||
assertSame(bf.getBean("store1"), resolved.get(0));
|
||||
assertSame(bf.getBean("store2"), resolved.get(1));
|
||||
|
||||
resolved = numberStoreProvider.stream().collect(Collectors.toSet());
|
||||
resolved = numberStoreProvider.stream().collect(Collectors.toList());
|
||||
assertEquals(2, resolved.size());
|
||||
assertTrue(resolved.contains(bf.getBean("store1")));
|
||||
assertTrue(resolved.contains(bf.getBean("store2")));
|
||||
assertSame(bf.getBean("store1"), resolved.get(0));
|
||||
assertSame(bf.getBean("store2"), resolved.get(1));
|
||||
|
||||
resolved = new HashSet<>();
|
||||
resolved = numberStoreProvider.toList();
|
||||
assertEquals(2, resolved.size());
|
||||
assertSame(bf.getBean("store2"), resolved.get(0));
|
||||
assertSame(bf.getBean("store1"), resolved.get(1));
|
||||
|
||||
resolved = new ArrayList<>();
|
||||
for (NumberStore<Double> instance : doubleStoreProvider) {
|
||||
resolved.add(instance);
|
||||
}
|
||||
assertEquals(1, resolved.size());
|
||||
assertTrue(resolved.contains(bf.getBean("store1")));
|
||||
|
||||
resolved = doubleStoreProvider.stream().collect(Collectors.toSet());
|
||||
resolved = doubleStoreProvider.stream().collect(Collectors.toList());
|
||||
assertEquals(1, resolved.size());
|
||||
assertTrue(resolved.contains(bf.getBean("store1")));
|
||||
|
||||
resolved = new HashSet<>();
|
||||
resolved = (List) doubleStoreProvider.toList();
|
||||
assertEquals(1, resolved.size());
|
||||
assertTrue(resolved.contains(bf.getBean("store1")));
|
||||
|
||||
resolved = new ArrayList<>();
|
||||
for (NumberStore<Float> instance : floatStoreProvider) {
|
||||
resolved.add(instance);
|
||||
}
|
||||
assertEquals(1, resolved.size());
|
||||
assertTrue(resolved.contains(bf.getBean("store2")));
|
||||
|
||||
resolved = floatStoreProvider.stream().collect(Collectors.toSet());
|
||||
resolved = floatStoreProvider.stream().collect(Collectors.toList());
|
||||
assertEquals(1, resolved.size());
|
||||
assertTrue(resolved.contains(bf.getBean("store2")));
|
||||
|
||||
resolved = (List) floatStoreProvider.toList();
|
||||
assertEquals(1, resolved.size());
|
||||
assertTrue(resolved.contains(bf.getBean("store2")));
|
||||
}
|
||||
@@ -991,7 +1006,12 @@ public class BeanFactoryGenericsTests {
|
||||
}
|
||||
|
||||
|
||||
public static class NumberStore<T extends Number> {
|
||||
public static class NumberStore<T extends Number> implements Comparable<NumberStore> {
|
||||
|
||||
@Override
|
||||
public int compareTo(NumberStore other) {
|
||||
return getClass().getName().compareTo(other.getClass().getName()) * -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user