spring四 處理自動裝配的歧義性

通常bean的自動裝配能夠給我們提供很大的方便,它會減少裝配應用程序組件時所需要的顯示配置的麻煩。不過,僅有一個bean匹配所需的結果時,自動裝配纔是有效的。如果符合條件的bean不只一個,這時就會阻礙Spring自動裝配屬性、構造器參數或方法參數。
下面我們就來製造一種自動裝配歧義性的情況:
public interface Dessert {}

@Component
public class Cake implements Dessert{
@Component
public class IceCream implements Dessert {}
@Component
public class Cookies implements Dessert{}
@Component
private Dessert dessert;
因爲這三個實現均使用了@Component註解,在組件掃描的時候,能夠發現它們並將其創建爲Spring應用上下文裏面的bean。然後,當Spring試圖自動裝配setDessert()中的Dessert參數時,它並沒有唯一、無歧義的可選值。在從多種甜點中做出選擇時,儘管大多數人並不會有什麼困難,但是Spring卻無法做出選擇。Spring此時別無他法,只好宣告失敗並拋出異常。更精確地講,Spring會拋出NoUniqueBeanDefinitionException 
解決辦法:

標示首選的bean

@Component
@Primary
public class IceCream implements Dessert {}

或者在如果你通過Java配置顯式地聲明IceCream,那麼@Bean方法應該如下所示

@Configuration
public class IceCreamBean {

    @Bean
    @Primary
    public Dessert iceCream(){
        return new IceCream();
    }
}

果你使用XML配置bean的話,同樣可以實現這樣的功能。<bean>元素有一個primary屬性用來指定首選的bean:

<bean id="iceCream" class="com.ambiguity.service.impl.IceCream" primary="true" />

但是,如果你標示了兩個或更多的首選bean,那麼它就無法正常工作了

2.限定自動裝配的bean

設置首選bean的侷限性在於@Primary無法將可選方案的範圍限定到唯一一個無歧義性的選
項中。它只能標示一個優先的可選方案。當首選bean的數量超過一個時,我們並沒有其他的
方法進一步縮小可選範圍。Spring的限定符能夠在所有可選的bean上進行縮小範圍的操作,最終能夠達到只

有一個bean滿足所規定的限制條件。

@Qualifier註解是使用限定符的主要方式。它可以與@Autowired和@Inject協同使用,在注入的時候指定想要注入進去的是哪個bean。

@AutoWired
@Qualifier("iceCream")
public void setDessert(Dessert dessert){
      this.dessert =dessert;  
}

 

這裏所設置的參數就是想要注入bean的ID。所有使用@Component註解聲明的類都會創建爲bean,並且bean的ID爲首字母變爲小寫的類名,因此@Qualifier("iceCream")指向的是組件掃描時所創建的bean並且這個bean是IceCream類的實例。但是,字符串類型的參數是不安全的,如果修改類名,這裏也會受到影響,所以我們需要創建自定義的限定符,所需要做的僅僅是在IceCream類上面添加@Qualifier("cold"):

@Component
@Qualifier("cold")
public class IceCream implements Dessert{...}

或者在顯式模式中:

@Bean
@Qualifier("cold")
public Dessert iceCream(){
        return new IceCream();
}

相應的setter方法上也將參數設置爲cold即可。

可是,如果有另外一個bean也同樣使用了cold限定符呢,還是會出現歧義,而java不允許同一個條目上重複出現相同類型的多個註解,否則編譯器會報錯,所以我們需要創建自定義的限定符註解,藉助這樣的註解來表達bean所希望限定的特性


如果有兩個面向特性的限定符要比基於bean ID的限定符更好一些。但是,如果多個bean都具備相同特性的話,這種做法也會出現問題在自動裝配Dessert bean的時候,我們再次遇到了歧義性的問題,需要使用更多的限定符來將可選範圍限定到只有一個bean。Java不允許在同一個條目上重複出現相同類型的多個註解所有不能用兩條@Qualifier

這樣我們將不再使用@Qualifier("cold"),而是使用自定義的註解



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章