这是我的代码:
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import java.util.List;
@Configuration
public class ResourceTest {
@Bean
TestBean testBean () {
return new TestBean();
}
@Bean
TargetBean targetBean () {
return new TargetBean("bean1");
}
@Bean(name = "myBean")
TargetBean targetBean2 () {
return new TargetBean("bean2");
}
@Bean(name = "myBean")
TargetBean targetBean3 () {
return new TargetBean("bean3");
}
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
ResourceTest.class);
TestBean bean = context.getBean(TestBean.class);
System.out.println(bean.getTargetBeanList());
}
public static class TestBean {
private List<TargetBean> targetBeanList;
@Resource(name = "myBean")
public void setXList (List<TargetBean> targetBeanList) {
this.targetBeanList = targetBeanList;
}
public List<TargetBean> getTargetBeanList () {
return targetBeanList;
}
}
public static class TargetBean {
private final String str;
public TargetBean (String str) {
this.str = str;
}
public String getStr () {
return str;
}
@Override
public String toString () {
return "TargetBean{ str='" + str + '\'' +
'}';
}
}
}
输出: [TargetBean {str ='bean2'}]
预期: 符合“myBean”的所有bean都应该在列表中,即bean2和bean3。
根据spring ref docs:
限定符也适用于类型化集合,如上所述,例如,Set。在这种情况下,根据声明的限定符的所有匹配bean都作为集合注入。这意味着限定符不必是唯一的;它们只是简单地构成过滤标准。例如,您可以使用相同的限定符值“action”定义多个MovieCatalog bean,所有这些bean都将注入到使用@Qualifier(“action”)注释的Set中。
我正在使用Spring 4.3.2.RELEASE。请帮忙解决这个问题。提前谢谢。
答案 0 :(得分:4)
name
带注释的元素中的@Bean
表示相应的bean定义的标识符。如果您有两个具有相同ID的bean定义,则稍后注册的bean将覆盖前一个。这就是你的豆子在这里发生的事情
@Bean(name = "myBean")
TargetBean targetBean2 () {
return new TargetBean("bean2");
}
@Bean(name = "myBean")
TargetBean targetBean3 () {
return new TargetBean("bean3");
}
您已将该部分文档链接起来,但您没有做过它所说的任何事情。
例如,您可以使用。定义多个
MovieCatalog
bean 相同的限定符值&#34;动作&#34;
让我们适应你的豆子
@Bean(name = "myBean2")
@Qualifier("myBean")
TargetBean targetBean2() {
return new TargetBean("bean2");
}
@Bean(name = "myBean3")
@Qualifier("myBean")
TargetBean targetBean3() {
return new TargetBean("bean3");
}
请注意,它们具有不同的ID(您可以省略@Bean
注释,而Spring将使用方法名称)但使用相同的@Qualifier
值。
然后
所有这些都将被注入带有
注释的集合中@Qualifier("action")
在注射点,使用
@Autowired
@Qualifier("myBean")
public void setXList(List<TargetBean> targetBeanList) {
this.targetBeanList = targetBeanList;
}
targetBeanList
现在将包含符合TargetBean
条件的两个myBean
bean。
Spring使用提供的@Resource
解析name
来查找bean的名称。它不了解@Qualifier
值。这就是我们将@Autowired
与@Qualifier
一起使用的原因。
答案 1 :(得分:0)
感谢Sotirios Delimanolis帮助我解决问题。
总结我的理解:
(1)&#39;名称&#39; @Bean中的元素(name = ....)是标识符而不是限定符。它可能与匹配限定符(我们使用@Autowired以及@Qualifier或@Resource的注入点)一起使用,但在我的情况下不能,因为id不能声明为相同。
(2)使用@Qualifier注释声明true限定符,该注释可与@Bean方法,@ Component(类)以及@Autowired(注入点)一起使用。
我想,当谈到通过某种名称匹配/过滤bean时,我们应该总是使用@Qualifier,即从不依赖于(1)。
顺便说一下,我想对上述回复发表评论..但由于某些原因,它不接受......;)