Spring Autowired(required = false) 說明

逸卿發表於2014-10-23

from:http://darkmasky.iteye.com/blog/1129828


  1. 當候選 Bean 數目不為 1 時的應對方法   
  2.   
  3. 在預設情況下使用 @Autowired 註釋進行自動注入時,Spring 容器中匹配的候選 Bean 數目必須有且僅有一個。當找不到一個匹配的 Bean 時,Spring 容器將丟擲 BeanCreationException 異常,並指出必須至少擁有一個匹配的 Bean。我們可以來做一個實驗:   
  4.   
  5.   
  6. 清單 10. 候選 Bean 數目為 0 時   
  7.                    
  8. <?xml version="1.0" encoding="UTF-8" ?>   
  9. <beans xmlns="http://www.springframework.org/schema/beans"  
  10.      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  11.       xsi:schemaLocation="http://www.springframework.org/schema/beans   
  12. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd ">   
  13.   
  14.      <bean class="org.springframework.beans.factory.annotation.   
  15.          AutowiredAnnotationBeanPostProcessor"/>   
  16.   
  17.      <bean id="boss" class="com.baobaotao.Boss"/>   
  18.   
  19.      <!-- 將 office Bean 註釋掉 -->   
  20.      <!-- <bean id="office" class="com.baobaotao.Office">   
  21.      <property name="officeNo" value="001"/>   
  22.      </bean>-->   
  23.   
  24.      <bean id="car" class="com.baobaotao.Car" scope="singleton">   
  25.          <property name="brand" value=" 紅旗 CA72"/>   
  26.          <property name="price" value="2000"/>   
  27.      </bean>   
  28. </beans>   
  29.   
  30.   
  31.   
  32. 由於 office Bean 被註釋掉了,所以 Spring 容器中將沒有型別為 Office 的 Bean 了,而 Boss 的 office 屬性標註了 @Autowired,當啟動 Spring 容器時,異常就產生了。   
  33.   
  34. 當不能確定 Spring 容器中一定擁有某個類的 Bean 時,可以在需要自動注入該類 Bean 的地方可以使用 @Autowired(required = false),這等於告訴 Spring:在找不到匹配 Bean 時也不報錯。來看一下具體的例子:   
  35.   
  36.   
  37. 清單 11. 使用 @Autowired(required = false)   
  38.                    
  39. package com.baobaotao;   
  40.   
  41. import org.springframework.beans.factory.annotation.Autowired;   
  42. import org.springframework.beans.factory.annotation.Required;   
  43.   
  44. public class Boss {   
  45.   
  46.     private Car car;   
  47.     private Office office;   
  48.   
  49.     @Autowired  
  50.     public void setCar(Car car) {   
  51.         this.car = car;   
  52.      }   
  53.     @Autowired(required = false)   
  54.     public void setOffice(Office office) {   
  55.         this.office = office;   
  56.      }   
  57.      …   
  58. }   
  59.   
  60.   
  61.   
  62. 當然,一般情況下,使用 @Autowired 的地方都是需要注入 Bean 的,使用了自動注入而又允許不注入的情況一般僅會在開發期或測試期碰到(如為了快速啟動 Spring 容器,僅引入一些模組的 Spring 配置檔案),所以 @Autowired(required = false) 會很少用到。   
  63.   
  64. 和找不到一個型別匹配 Bean 相反的一個錯誤是:如果 Spring 容器中擁有多個候選 Bean,Spring 容器在啟動時也會丟擲 BeanCreationException 異常。來看下面的例子:   
  65.   
  66.   
  67. 清單 12. 在 beans.xml 中配置兩個 Office 型別的 Bean   
  68.                    
  69. …   
  70. <bean id="office" class="com.baobaotao.Office">   
  71.      <property name="officeNo" value="001"/>   
  72. </bean>   
  73. <bean id="office2" class="com.baobaotao.Office">   
  74.      <property name="officeNo" value="001"/>   
  75. </bean>   
  76. …   
  77.   
  78.   
  79.   
  80. 我們在 Spring 容器中配置了兩個型別為 Office 型別的 Bean,當對 Boss 的 office 成員變數進行自動注入時,Spring 容器將無法確定到底要用哪一個 Bean,因此異常發生了。   
  81.   
  82. Spring 允許我們通過 @Qualifier 註釋指定注入 Bean 的名稱,這樣歧義就消除了,可以通過下面的方法解決異常:   
  83.   
  84.   
  85. 清單 13. 使用 @Qualifier 註釋指定注入 Bean 的名稱   
  86.                    
  87. @Autowired  
  88. public void setOffice(@Qualifier("office")Office office) {   
  89.     this.office = office;   
  90. }   
  91.   
  92.   
  93.   
  94. @Qualifier("office") 中的 office 是 Bean 的名稱,所以 @Autowired 和 @Qualifier 結合使用時,自動注入的策略就從 byType 轉變成 byName 了。@Autowired 可以對成員變數、方法以及建構函式進行註釋,而 @Qualifier 的標註物件是成員變數、方法入參、建構函式入參。正是由於註釋物件的不同,所以 Spring 不將 @Autowired 和 @Qualifier 統一成一個註釋類。下面是對成員變數和建構函式入參進行註釋的程式碼:   
  95.   
  96. 對成員變數進行註釋:   
  97.   
  98.   
  99. 清單 14. 對成員變數使用 @Qualifier 註釋   
  100.                    
  101. public class Boss {   
  102.     @Autowired  
  103.     private Car car;   
  104.   
  105.     @Autowired  
  106.     @Qualifier("office")   
  107.     private Office office;   
  108.      …   
  109. }   
  110.   
  111.   
  112.   
  113. 對建構函式入參進行註釋:   
  114.   
  115.   
  116. 清單 15. 對建構函式變數使用 @Qualifier 註釋   
  117.                    
  118. public class Boss {   
  119.     private Car car;   
  120.     private Office office;   
  121.   
  122.     @Autowired  
  123.     public Boss(Car car , @Qualifier("office")Office office){   
  124.         this.car = car;   
  125.         this.office = office ;   
  126.      }   
  127. }   
  128.   
  129.   
  130.   
  131. @Qualifier 只能和 @Autowired 結合使用,是對 @Autowired 有益的補充。一般來講,@Qualifier 對方法簽名中入參進行註釋會降低程式碼的可讀性,而對成員變數註釋則相對好一些。   

相關文章