显示我的问题的简单测试类:
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringTest.OptionalConfiguration.class)
public class SpringTest {
static class Item extends Object {}
@Configuration
static class OptionalConfiguration {
@Bean
List<Item> someString() {
return new ArrayList<>();
}
@Bean
Object foo(List<Item> obj) {
return new Object();
}
}
@Test
public void testThis() {
}
}
结果:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [SpringTest$Item] found for dependency [collection of SpringTest$Item]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
如果我从 List<Item>
改变至 Item
,一切正常。
这是设计使然吗?任何解决方法?我需要提供 List
项目 - 有时是空的,有时是项目,具体取决于运行时配置。
我知道如果我指定类型为 Item 的 bean, Autowiring List<Item>
作品。但是,我想要一个类型为 List<Item>
的 bean。 (或者如果我不能拥有它,一个 List
)。
使用 Spring 4.2.4。
最佳答案
该代码片段在 Spring 4.3+ 中可以正常工作。 documentation州
That said, as of 4.3, collection/map and array types can be matched through Spring’s
@Autowired
type matching algorithm as well [which is also used for@Bean
argument resolution], as long as the element type information is preserved in@Bean
return type signatures or collection inheritance hierarchies. In this case, qualifier values can be used to select among same-typed collections, as outlined in the previous paragraph.
4.3 之前,当 Spring 出现时
@Bean
Object foo(List<Item> obj) {
它尝试动态创建一个 List
对象,其中包含在 ApplicationContext
中找到的所有 Item
bean。您的 ApplicationContext
不包含任何内容,因此 Spring 报告错误。
这里有一些解决方法。这个
@Bean
Object foo() {
List<Item> someString = someString();
return new Object();
}
直接使用缓存的bean工厂方法,someString
。
这个
@Resource(name = "someString")
private List<Item> items;
// and access 'items' wherever you need it in the configuration
有效是因为
If you intend to express annotation-driven injection by name, do not primarily use @Autowired, even if is technically capable of referring to a bean name through @Qualifier values. Instead, use the JSR-250 @Resource annotation, which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process. @Autowired has rather different semantics: After selecting candidate beans by type, the specified String qualifier value will be considered within those type-selected candidates only, e.g. matching an "account" qualifier against beans marked with the same qualifier label.
关于java - Spring 无法解析类型为 List 的 bean 的 @Bean 依赖关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41490496/