我有一个提供单个bean的配置和一个提供一个bean列表的配置。所有这些bean具有相同的类型。
使用这些配置启动应用程序上下文时,我看到Bean类型的自动装配列表仅包含单个Bean。 我希望它包含该类型的所有bean。我使用Spring 5.2.0。
我将其简化为一种配置:如果我提供一个bean和一个bean列表,将仅使用单个bean 。
在以下测试中将其复制。失败,因为列表仅包含“ A”和“ D”(表明它没有自动装配bean列表):
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { TestConfiguration.class })
class AutowiringListsTest {
@Autowired
private List<TestBean> testBeanList;
@Test
void testThatBothConfigurationsContributeToBeanList() {
final List<String> idList = testBeanList.stream().map(TestBean::getId).sorted().collect(Collectors.toList());
assertThat(idList, hasItems("A", "B", "C", "D"));
}
@Configuration
public static class TestConfiguration {
@Bean
public TestBean someBean() {
return new TestBean("A");
}
@Bean
public List<TestBean> someMoreBeans() {
return Arrays.asList(new TestBean("B"), new TestBean("C"));
}
@Bean
public TestBean anotherBean() {
return new TestBean("D");
}
}
public static class TestBean {
private final String id;
public TestBean(final String id) {
this.id = id;
}
private String getId() {
return id;
}
}
}
我想让它运行,以便多个模块可以提供某种类型的bean。
如何运行此程序?在什么情况下,Spring的行为有意义?
答案 0 :(得分:0)
我可以通过引入TestBeanFactory
来解决此问题。每个要贡献到TestBean
列表的配置都提供了一个工厂。
@Configuration
public static class TestConfiguration {
/** Implemented once in the configuration that defines <code>TestBean</code>. */
@Bean
public List<TestBean> testBeansFromFactory(Collection<TestBeanFactory> factories) {
return factories.stream().map(TestBeanFactory::createTestBeans).flatMap(Collection::stream)
.collect(toList());
}
// Further methods can be defined in various configurations that want to add to the list of TestBeans.
@Bean
public TestBeanFactory someBean() {
return () -> Arrays.asList(new TestBean("A"));
}
@Bean
public TestBeanFactory someMoreBeans() {
return () -> Arrays.asList(new TestBean("B"), new TestBean("C"));
}
@Bean
public TestBeanFactory anotherBean() {
return () -> Arrays.asList(new TestBean("D"));
}
}
public static class TestBean { ... }
public static interface TestBeanFactory {
public Collection<TestBean> createTestBeans();
}
那行得通,而且只是更多的代码。
M.Deinum在评论中指出了Spring的行为是一致的:
在定义List类型的bean时,将使用它。自动装配基于类型,它将尝试检测特定类型的Bean。集合(以及地图)是一个特殊的集合,用于查找给定类型的所有依赖项。