Support filtered/unfiltered stream access on ObjectProvider

Closes gh-34318
Closes gh-34203
This commit is contained in:
Juergen Hoeller
2025-02-03 15:04:27 +01:00
parent 2df8ea94e0
commit 8c2b44bd6c
4 changed files with 213 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1515,12 +1515,16 @@ class DefaultListableBeanFactoryTests {
bd1.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, Ordered.LOWEST_PRECEDENCE);
lbf.registerBeanDefinition("bean1", bd1);
GenericBeanDefinition bd2 = new GenericBeanDefinition();
bd2.setBeanClass(TestBean.class);
bd2.setBeanClass(DerivedTestBean.class);
bd2.setPropertyValues(new MutablePropertyValues(List.of(new PropertyValue("name", "highest"))));
bd2.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, Ordered.HIGHEST_PRECEDENCE);
lbf.registerBeanDefinition("bean2", bd2);
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream().map(TestBean::getName))
.containsExactly("highest", "lowest");
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED).map(TestBean::getName))
.containsExactly("highest", "lowest");
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(clazz -> !DerivedTestBean.class.isAssignableFrom(clazz))
.map(TestBean::getName)).containsExactly("lowest");
}
@Test
@@ -1540,6 +1544,8 @@ class DefaultListableBeanFactoryTests {
lbf.registerBeanDefinition("bean2", bd2);
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream().map(TestBean::getName))
.containsExactly("fromLowestPrecedenceTestBeanFactoryBean", "fromHighestPrecedenceTestBeanFactoryBean");
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED).map(TestBean::getName))
.containsExactly("fromLowestPrecedenceTestBeanFactoryBean", "fromHighestPrecedenceTestBeanFactoryBean");
}
@Test
@@ -1934,6 +1940,11 @@ class DefaultListableBeanFactoryTests {
assertThat(resolved).hasSize(2);
assertThat(resolved).contains(lbf.getBean("bd1"));
assertThat(resolved).contains(lbf.getBean("bd2"));
resolved = provider.stream(ObjectProvider.UNFILTERED).collect(Collectors.toSet());
assertThat(resolved).hasSize(2);
assertThat(resolved).contains(lbf.getBean("bd1"));
assertThat(resolved).contains(lbf.getBean("bd2"));
}
@Test
@@ -1983,6 +1994,11 @@ class DefaultListableBeanFactoryTests {
assertThat(resolved).hasSize(2);
assertThat(resolved).contains(lbf.getBean("bd1"));
assertThat(resolved).contains(lbf.getBean("bd2"));
resolved = provider.stream(ObjectProvider.UNFILTERED).collect(Collectors.toSet());
assertThat(resolved).hasSize(2);
assertThat(resolved).contains(lbf.getBean("bd1"));
assertThat(resolved).contains(lbf.getBean("bd2"));
}
@Test
@@ -2378,11 +2394,20 @@ class DefaultListableBeanFactoryTests {
parentBf.registerBeanDefinition("highPriorityTestBean", bd2);
ObjectProvider<TestBean> testBeanProvider = lbf.getBeanProvider(ResolvableType.forClass(TestBean.class));
List<TestBean> resolved = testBeanProvider.orderedStream().toList();
assertThat(resolved).containsExactly(
assertThat(testBeanProvider.orderedStream()).containsExactly(
lbf.getBean("highPriorityTestBean", TestBean.class),
lbf.getBean("lowPriorityTestBean", TestBean.class),
lbf.getBean("plainTestBean", TestBean.class));
assertThat(testBeanProvider.orderedStream(clazz -> clazz != TestBean.class).toList()).containsExactly(
lbf.getBean("highPriorityTestBean", TestBean.class),
lbf.getBean("lowPriorityTestBean", TestBean.class));
assertThat(testBeanProvider.stream()).containsExactly(
lbf.getBean("plainTestBean", TestBean.class),
lbf.getBean("lowPriorityTestBean", TestBean.class),
lbf.getBean("highPriorityTestBean", TestBean.class));
assertThat(testBeanProvider.orderedStream(clazz -> clazz != TestBean.class).toList()).containsExactly(
lbf.getBean("lowPriorityTestBean", TestBean.class),
lbf.getBean("highPriorityTestBean", TestBean.class));
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -64,6 +64,7 @@ import org.springframework.beans.factory.support.AutowireCandidateQualifier;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.testfixture.beans.DerivedTestBean;
import org.springframework.beans.testfixture.beans.ITestBean;
import org.springframework.beans.testfixture.beans.IndexedTestBean;
import org.springframework.beans.testfixture.beans.NestedTestBean;
@@ -1605,7 +1606,11 @@ class AutowiredAnnotationBeanPostProcessorTests {
assertThat(testBeans).containsExactly(bf.getBean("testBean1", TestBean.class), bf.getBean("testBean2", TestBean.class));
testBeans = bean.streamTestBeans();
assertThat(testBeans).containsExactly(bf.getBean("testBean1", TestBean.class), bf.getBean("testBean2", TestBean.class));
testBeans = bean.sortedTestBeans();
testBeans = bean.streamTestBeansInOrder();
assertThat(testBeans).containsExactly(bf.getBean("testBean1", TestBean.class), bf.getBean("testBean2", TestBean.class));
testBeans = bean.allTestBeans();
assertThat(testBeans).containsExactly(bf.getBean("testBean1", TestBean.class), bf.getBean("testBean2", TestBean.class));
testBeans = bean.allTestBeansInOrder();
assertThat(testBeans).containsExactly(bf.getBean("testBean1", TestBean.class), bf.getBean("testBean2", TestBean.class));
}
@@ -1632,7 +1637,13 @@ class AutowiredAnnotationBeanPostProcessorTests {
testBeans = bean.streamTestBeans();
assertThat(testBeans).hasSize(1);
assertThat(testBeans).contains(bf.getBean("testBean", TestBean.class));
testBeans = bean.sortedTestBeans();
testBeans = bean.streamTestBeansInOrder();
assertThat(testBeans).hasSize(1);
assertThat(testBeans).contains(bf.getBean("testBean", TestBean.class));
testBeans = bean.allTestBeans();
assertThat(testBeans).hasSize(1);
assertThat(testBeans).contains(bf.getBean("testBean", TestBean.class));
testBeans = bean.allTestBeansInOrder();
assertThat(testBeans).hasSize(1);
assertThat(testBeans).contains(bf.getBean("testBean", TestBean.class));
}
@@ -1656,7 +1667,11 @@ class AutowiredAnnotationBeanPostProcessorTests {
assertThat(testBeans).isEmpty();
testBeans = bean.streamTestBeans();
assertThat(testBeans).isEmpty();
testBeans = bean.sortedTestBeans();
testBeans = bean.streamTestBeansInOrder();
assertThat(testBeans).isEmpty();
testBeans = bean.allTestBeans();
assertThat(testBeans).isEmpty();
testBeans = bean.allTestBeansInOrder();
assertThat(testBeans).isEmpty();
}
@@ -1678,7 +1693,9 @@ class AutowiredAnnotationBeanPostProcessorTests {
assertThat(bean.iterateTestBeans()).containsExactly(testBean1, testBean2);
assertThat(bean.forEachTestBeans()).containsExactly(testBean1, testBean2);
assertThat(bean.streamTestBeans()).containsExactly(testBean1, testBean2);
assertThat(bean.sortedTestBeans()).containsExactly(testBean1, testBean2);
assertThat(bean.streamTestBeansInOrder()).containsExactly(testBean1, testBean2);
assertThat(bean.allTestBeans()).containsExactly(testBean1, testBean2);
assertThat(bean.allTestBeansInOrder()).containsExactly(testBean1, testBean2);
}
@Test
@@ -1706,7 +1723,9 @@ class AutowiredAnnotationBeanPostProcessorTests {
assertThat(bean.iterateTestBeans()).containsExactly(testBean1, testBean2);
assertThat(bean.forEachTestBeans()).containsExactly(testBean1, testBean2);
assertThat(bean.streamTestBeans()).containsExactly(testBean1, testBean2);
assertThat(bean.sortedTestBeans()).containsExactly(testBean2, testBean1);
assertThat(bean.streamTestBeansInOrder()).containsExactly(testBean2, testBean1);
assertThat(bean.allTestBeans()).containsExactly(testBean1, testBean2);
assertThat(bean.allTestBeansInOrder()).containsExactly(testBean2, testBean1);
}
@Test
@@ -1722,8 +1741,47 @@ class AutowiredAnnotationBeanPostProcessorTests {
bf.registerBeanDefinition("testBean2", tb2);
ObjectProviderInjectionBean bean = bf.getBean("annotatedBean", ObjectProviderInjectionBean.class);
assertThat(bean.sortedTestBeans()).containsExactly(bf.getBean("testBean2", TestBean.class),
assertThat(bean.streamTestBeansInOrder()).containsExactly(bf.getBean("testBean2", TestBean.class),
bf.getBean("testBean1", TestBean.class));
assertThat(bean.allTestBeansInOrder()).containsExactly(bf.getBean("testBean2", TestBean.class),
bf.getBean("testBean1", TestBean.class));
}
@Test
void objectProviderInjectionWithNonCandidatesInStream() {
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ObjectProviderInjectionBean.class));
RootBeanDefinition tb1 = new RootBeanDefinition(TestBeanFactory.class);
tb1.setFactoryMethodName("newTestBean1");
bf.registerBeanDefinition("testBean1", tb1);
RootBeanDefinition tb2 = new RootBeanDefinition(TestBeanFactory.class);
tb2.setFactoryMethodName("newTestBean2");
bf.registerBeanDefinition("testBean2", tb2);
RootBeanDefinition tb3 = new RootBeanDefinition(TestBean.class);
tb3.setAutowireCandidate(false);
tb3.setLazyInit(true);
bf.registerBeanDefinition("testBean3", tb3);
RootBeanDefinition tb4 = new RootBeanDefinition(DerivedTestBean.class);
tb4.setDefaultCandidate(false);
tb4.setLazyInit(true);
bf.registerBeanDefinition("testBean4", tb4);
ObjectProviderInjectionBean bean = bf.getBean("annotatedBean", ObjectProviderInjectionBean.class);
assertThat(bean.streamTestBeans()).containsExactly(bf.getBean("testBean1", TestBean.class),
bf.getBean("testBean2", TestBean.class));
assertThat(bean.streamTestBeansInOrder()).containsExactly(bf.getBean("testBean2", TestBean.class),
bf.getBean("testBean1", TestBean.class));
assertThat(bf.containsSingleton("testBean3")).isFalse();
assertThat(bean.plainTestBeans()).containsExactly(bf.getBean("testBean1", TestBean.class),
bf.getBean("testBean2", TestBean.class), bf.getBean("testBean3", TestBean.class));
assertThat(bean.plainTestBeansInOrder()).containsExactly(bf.getBean("testBean2", TestBean.class),
bf.getBean("testBean1", TestBean.class), bf.getBean("testBean3", TestBean.class));
assertThat(bf.containsSingleton("testBean4")).isFalse();
assertThat(bean.allTestBeans()).containsExactly(bf.getBean("testBean1", TestBean.class),
bf.getBean("testBean2", TestBean.class), bf.getBean("testBean3", TestBean.class),
bf.getBean("testBean4", TestBean.class));
assertThat(bean.allTestBeansInOrder()).containsExactly(bf.getBean("testBean2", TestBean.class),
bf.getBean("testBean1", TestBean.class), bf.getBean("testBean3", TestBean.class),
bf.getBean("testBean4", TestBean.class));
}
@Test
@@ -3304,9 +3362,25 @@ class AutowiredAnnotationBeanPostProcessorTests {
return this.testBean.stream().toList();
}
public List<TestBean> sortedTestBeans() {
public List<TestBean> streamTestBeansInOrder() {
return this.testBean.orderedStream().toList();
}
public List<TestBean> plainTestBeans() {
return this.testBean.stream(clazz -> !DerivedTestBean.class.isAssignableFrom(clazz)).toList();
}
public List<TestBean> plainTestBeansInOrder() {
return this.testBean.orderedStream(clazz -> !DerivedTestBean.class.isAssignableFrom(clazz)).toList();
}
public List<TestBean> allTestBeans() {
return this.testBean.stream(ObjectProvider.UNFILTERED).toList();
}
public List<TestBean> allTestBeansInOrder() {
return this.testBean.orderedStream(ObjectProvider.UNFILTERED).toList();
}
}