diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 13b5779c377..e6b927a0014 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -1459,7 +1459,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto candidates.put(candidateName, beanInstance); } } - else if (containsSingleton(candidateName)) { + else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor && + ((StreamDependencyDescriptor) descriptor).isOrdered())) { Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this); candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance)); } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java index ad1736c9ecf..6c87289928f 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java @@ -71,7 +71,6 @@ 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.*; @@ -1290,12 +1289,12 @@ public class AutowiredAnnotationBeanPostProcessorTests { @Test public void testObjectProviderInjectionWithTargetPrimary() { bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ObjectProviderInjectionBean.class)); - RootBeanDefinition tb1 = new RootBeanDefinition(OrderedTestBean.class); - tb1.getPropertyValues().add("order", 1); + RootBeanDefinition tb1 = new RootBeanDefinition(TestBeanFactory.class); + tb1.setFactoryMethodName("newTestBean1"); tb1.setPrimary(true); bf.registerBeanDefinition("testBean1", tb1); - RootBeanDefinition tb2 = new RootBeanDefinition(OrderedTestBean.class); - tb2.getPropertyValues().add("order", 0); + RootBeanDefinition tb2 = new RootBeanDefinition(TestBeanFactory.class); + tb2.setFactoryMethodName("newTestBean2"); tb2.setLazyInit(true); bf.registerBeanDefinition("testBean2", tb2); @@ -1321,8 +1320,27 @@ public class AutowiredAnnotationBeanPostProcessorTests { assertSame(bf.getBean("testBean2"), testBeans.get(1)); testBeans = bean.sortedTestBeans(); assertEquals(2, testBeans.size()); + assertSame(bf.getBean("testBean2"), testBeans.get(0)); assertSame(bf.getBean("testBean1"), testBeans.get(1)); + } + + @Test + public void testObjectProviderInjectionWithUnresolvedOrderedStream() { + bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ObjectProviderInjectionBean.class)); + RootBeanDefinition tb1 = new RootBeanDefinition(TestBeanFactory.class); + tb1.setFactoryMethodName("newTestBean1"); + tb1.setPrimary(true); + bf.registerBeanDefinition("testBean1", tb1); + RootBeanDefinition tb2 = new RootBeanDefinition(TestBeanFactory.class); + tb2.setFactoryMethodName("newTestBean2"); + tb2.setLazyInit(true); + bf.registerBeanDefinition("testBean2", tb2); + + ObjectProviderInjectionBean bean = (ObjectProviderInjectionBean) bf.getBean("annotatedBean"); + List testBeans = bean.sortedTestBeans(); + assertEquals(2, testBeans.size()); assertSame(bf.getBean("testBean2"), testBeans.get(0)); + assertSame(bf.getBean("testBean1"), testBeans.get(1)); } @Test @@ -2981,21 +2999,6 @@ public class AutowiredAnnotationBeanPostProcessorTests { } - public static class OrderedTestBean extends TestBean implements Ordered { - - private int order; - - public void setOrder(int order) { - this.order = order; - } - - @Override - public int getOrder() { - return this.order; - } - } - - public static class OrderedNestedTestBean extends NestedTestBean implements Ordered { private int order; @@ -3861,4 +3864,18 @@ public class AutowiredAnnotationBeanPostProcessorTests { } } + + public static class TestBeanFactory { + + @Order(1) + public static TestBean newTestBean1() { + return new TestBean(); + } + + @Order(0) + public static TestBean newTestBean2() { + return new TestBean(); + } + } + } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanFactoryGenericsTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanFactoryGenericsTests.java index 4237a5da4d0..3ed1b9bec66 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanFactoryGenericsTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanFactoryGenericsTests.java @@ -43,9 +43,10 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.config.TypedStringValue; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.beans.propertyeditors.CustomNumberEditor; -import org.springframework.core.Ordered; import org.springframework.core.OverridingClassLoader; import org.springframework.core.ResolvableType; +import org.springframework.core.annotation.AnnotationAwareOrderComparator; +import org.springframework.core.annotation.Order; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.UrlResource; import org.springframework.tests.Assume; @@ -83,7 +84,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericListProperty() throws MalformedURLException { + public void testGenericListProperty() throws Exception { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class); @@ -100,7 +101,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericListPropertyWithAutowiring() throws MalformedURLException { + public void testGenericListPropertyWithAutowiring() throws Exception { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); bf.registerSingleton("resource1", new UrlResource("http://localhost:8080")); bf.registerSingleton("resource2", new UrlResource("http://localhost:9090")); @@ -223,7 +224,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericSetListConstructor() throws MalformedURLException { + public void testGenericSetListConstructor() throws Exception { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class); @@ -246,7 +247,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericSetListConstructorWithAutowiring() throws MalformedURLException { + public void testGenericSetListConstructorWithAutowiring() throws Exception { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); bf.registerSingleton("integer1", new Integer(4)); bf.registerSingleton("integer2", new Integer(5)); @@ -265,7 +266,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericSetListConstructorWithOptionalAutowiring() throws MalformedURLException { + public void testGenericSetListConstructorWithOptionalAutowiring() throws Exception { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); bf.registerSingleton("resource1", new UrlResource("http://localhost:8080")); bf.registerSingleton("resource2", new UrlResource("http://localhost:9090")); @@ -280,7 +281,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericSetMapConstructor() throws MalformedURLException { + public void testGenericSetMapConstructor() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class); @@ -303,7 +304,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericMapResourceConstructor() throws MalformedURLException { + public void testGenericMapResourceConstructor() throws Exception { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class); @@ -322,7 +323,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericMapMapConstructor() throws MalformedURLException { + public void testGenericMapMapConstructor() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class); @@ -348,7 +349,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericMapMapConstructorWithSameRefAndConversion() throws MalformedURLException { + public void testGenericMapMapConstructorWithSameRefAndConversion() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class); @@ -371,7 +372,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericMapMapConstructorWithSameRefAndNoConversion() throws MalformedURLException { + public void testGenericMapMapConstructorWithSameRefAndNoConversion() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class); @@ -391,7 +392,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericMapWithKeyTypeConstructor() throws MalformedURLException { + public void testGenericMapWithKeyTypeConstructor() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class); @@ -408,7 +409,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericMapWithCollectionValueConstructor() throws MalformedURLException { + public void testGenericMapWithCollectionValueConstructor() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); bf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() { @Override @@ -455,7 +456,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericSetListFactoryMethod() throws MalformedURLException { + public void testGenericSetListFactoryMethod() throws Exception { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class); rbd.setFactoryMethodName("createInstance"); @@ -479,7 +480,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericSetMapFactoryMethod() throws MalformedURLException { + public void testGenericSetMapFactoryMethod() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class); rbd.setFactoryMethodName("createInstance"); @@ -503,7 +504,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericMapResourceFactoryMethod() throws MalformedURLException { + public void testGenericMapResourceFactoryMethod() throws Exception { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class); rbd.setFactoryMethodName("createInstance"); @@ -523,7 +524,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericMapMapFactoryMethod() throws MalformedURLException { + public void testGenericMapMapFactoryMethod() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class); rbd.setFactoryMethodName("createInstance"); @@ -547,7 +548,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericMapWithKeyTypeFactoryMethod() throws MalformedURLException { + public void testGenericMapWithKeyTypeFactoryMethod() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class); rbd.setFactoryMethodName("createInstance"); @@ -565,7 +566,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericMapWithCollectionValueFactoryMethod() throws MalformedURLException { + public void testGenericMapWithCollectionValueFactoryMethod() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); bf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() { @Override @@ -625,7 +626,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericallyTypedIntegerBean() throws Exception { + public void testGenericallyTypedIntegerBean() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(bf).loadBeanDefinitions( new ClassPathResource("genericBeanTests.xml", getClass())); @@ -636,7 +637,7 @@ public class BeanFactoryGenericsTests { } @Test - public void testGenericallyTypedSetOfIntegerBean() throws Exception { + public void testGenericallyTypedSetOfIntegerBean() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(bf).loadBeanDefinitions( new ClassPathResource("genericBeanTests.xml", getClass())); @@ -846,10 +847,15 @@ public class BeanFactoryGenericsTests { @Test public void testGenericMatchingWithFullTypeDifferentiation() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); + bf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); bf.setAutowireCandidateResolver(new GenericTypeAwareAutowireCandidateResolver()); - bf.registerBeanDefinition("store1", new RootBeanDefinition(DoubleStore.class)); - bf.registerBeanDefinition("store2", new RootBeanDefinition(FloatStore.class)); + RootBeanDefinition bd1 = new RootBeanDefinition(NumberStoreFactory.class); + bd1.setFactoryMethodName("newDoubleStore"); + bf.registerBeanDefinition("store1", bd1); + RootBeanDefinition bd2 = new RootBeanDefinition(NumberStoreFactory.class); + bd2.setFactoryMethodName("newFloatStore"); + bf.registerBeanDefinition("store2", bd2); bf.registerBeanDefinition("numberBean", new RootBeanDefinition(NumberBean.class, RootBeanDefinition.AUTOWIRE_CONSTRUCTOR, false)); @@ -922,7 +928,7 @@ public class BeanFactoryGenericsTests { assertEquals(1, resolved.size()); assertTrue(resolved.contains(bf.getBean("store1"))); - resolved = (List) doubleStoreProvider.orderedStream().collect(Collectors.toList()); + resolved = doubleStoreProvider.orderedStream().collect(Collectors.toList()); assertEquals(1, resolved.size()); assertTrue(resolved.contains(bf.getBean("store1"))); @@ -937,11 +943,31 @@ public class BeanFactoryGenericsTests { assertEquals(1, resolved.size()); assertTrue(resolved.contains(bf.getBean("store2"))); - resolved = (List) floatStoreProvider.orderedStream().collect(Collectors.toList()); + resolved = floatStoreProvider.orderedStream().collect(Collectors.toList()); assertEquals(1, resolved.size()); assertTrue(resolved.contains(bf.getBean("store2"))); } + @Test + public void testGenericMatchingWithUnresolvedOrderedStream() { + DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); + bf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); + bf.setAutowireCandidateResolver(new GenericTypeAwareAutowireCandidateResolver()); + + RootBeanDefinition bd1 = new RootBeanDefinition(NumberStoreFactory.class); + bd1.setFactoryMethodName("newDoubleStore"); + bf.registerBeanDefinition("store1", bd1); + RootBeanDefinition bd2 = new RootBeanDefinition(NumberStoreFactory.class); + bd2.setFactoryMethodName("newFloatStore"); + bf.registerBeanDefinition("store2", bd2); + + ObjectProvider> numberStoreProvider = bf.getBeanProvider(ResolvableType.forClass(NumberStore.class)); + List> resolved = numberStoreProvider.orderedStream().collect(Collectors.toList()); + assertEquals(2, resolved.size()); + assertSame(bf.getBean("store2"), resolved.get(0)); + assertSame(bf.getBean("store1"), resolved.get(1)); + } + @SuppressWarnings("serial") public static class NamedUrlList extends LinkedList { @@ -1009,21 +1035,11 @@ public class BeanFactoryGenericsTests { } - public static class DoubleStore extends NumberStore implements Ordered { - - @Override - public int getOrder() { - return 1; - } + public static class DoubleStore extends NumberStore { } - public static class FloatStore extends NumberStore implements Ordered { - - @Override - public int getOrder() { - return 0; - } + public static class FloatStore extends NumberStore { } @@ -1047,4 +1063,18 @@ public class BeanFactoryGenericsTests { } } + + public static class NumberStoreFactory { + + @Order(1) + public static NumberStore newDoubleStore() { + return new DoubleStore(); + } + + @Order(0) + public static NumberStore newFloatStore() { + return new FloatStore(); + } + } + }