2016-08-18 124 views
1

這裏是我的代碼:如何使用相同的@Qualifier注入bean列表?

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 {海峽= 'bean2'}]

預計: 所有豆類資格 「爲myBean」 應該是列表中即bean2和bean3。

根據彈簧REF文檔:

限定符也適用於類型集合,如上所討論的,例如,設置。在這種情況下,根據聲明的限定符的所有匹配的Bean將作爲集合注入。這意味着限定詞不必是唯一的;它們只是構成過濾標準。例如,您可以使用相同的限定符值「action」定義多個MovieCatalog bean,所有這些都將被注入到由@Qualifier(「action」)註釋的Set中。

我使用Spring 4.3.2.RELEASE。請幫助解決這個問題。提前致謝。

回答

2

@Bean帶有註釋的元素中的name表示相應的bean定義的標識符。如果您有兩個具有相同ID的bean定義,稍後註冊的定義將覆蓋前一個。這是你的豆這裏所發生

@Bean(name = "myBean") 
TargetBean targetBean2() { 
    return new TargetBean("bean2"); 
} 

@Bean(name = "myBean") 
TargetBean targetBean3() { 
    return new TargetBean("bean3"); 
} 

你鏈接的文檔的一部分,但你沒有做任何的它說的東西。

例如,您可以定義多個MovieCatalog豆與 相同限定值「動作」

讓我們適應,爲您的豆

@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 name解決@Resource。它不知道@Qualifier值。這就是爲什麼我們在上面使用@Autowired@Qualifier

+0

太棒了!這樣可行。謝謝。 –

0

感謝Sotirios Delimanolis幫助我解決問題。

總結我的理解:

(1)在@Bean '名稱' 元件(名稱= ....)是一個標識符不是一個限定符。它可能與匹配限定符(我們使用@Autowired和@Qualifier或@Resource一起使用的注入點)一起工作,但在我的情況下不能使用,因爲ids不能聲明爲相同。 (2)真正的限定符是用@Qualifier註釋來聲明的,它可以和@Bean方法,@Component(類)一起使用,並且和@Autowired(注入點)一起使用。

我想,當涉及到通過某個名稱來匹配/過濾bean時,我們應該總是使用@Qualifier,即從不依賴(1)。

順便說一句我想把評論,以上的答覆..但由於某些原因,它不接受..;)

相關問題