天天看點

springMVC注解——@Autowired

使用 @Autowired 注解進行裝配,隻能是根據類型進行比對。@Autowired 注解可以用于 Setter 方法、構造函數、字段,甚至普通方法,前提是方法必須有至少一個參數。@Autowired 可以用于數組和使用泛型的集合類型。然後 Spring 會将容器中所有類型符合的 Bean 注入進來。@Autowired 标注作用于 Map 類型時,如果 Map 的 key 為 String 類型,則 Spring 會将容器中所有類型符合 Map 的 value 對應的類型的 Bean 增加進來,用 Bean 的 id 或 name 作為 Map 的 key。

@Autowired 标注作用于普通方法時,會産生一個副作用,就是在容器初始化該 Bean 執行個體的時候就會調用該方法。當然,前提是執行了自動裝配,對于不滿足裝配條件的情況,該方法也不會被執行。

當标注了 @Autowired 後,自動注入不能滿足,則會抛出異常。我們可以給 @Autowired 标注增加一個 required=false 屬性,以改變這個行為。另外,每一個類中隻能有一個構造函數的 @Autowired.required() 屬性為 true。否則就出問題了。如果用 @Autowired 同時标注了多個構造函數,那麼,Spring 将采用貪心算法比對構造函數 ( 構造函數最長 )。

@Autowired 還有一個作用就是,如果将其标注在 BeanFactory 類型、ApplicationContext 類型、ResourceLoader 類型、ApplicationEventPublisher 類型、MessageSource 類型上,那麼 Spring 會自動注入這些實作類的執行個體,不需要額外的操作。

當容器中存在多個 Bean 的類型與需要注入的相同時,注入将不能執行,我們可以給 @Autowired 增加一個候選值,做法是在 @Autowired 後面增加一個 @Qualifier 标注,提供一個 String 類型的值作為候選的 Bean 的名字。舉例如下:

@Autowired(required=false) 
 @Qualifier("ppp") 
 public void setPerson(person p){}
           

@Qualifier 甚至可以作用于方法的參數 ( 對于方法隻有一個參數的情況,我們可以将 @Qualifer 标注放置在方法聲明上面,但是推薦放置在參數前面 ),舉例如下:

@Autowired(required=false) 
 public void sayHello(@Qualifier("ppp")Person p,String name){}
我們可以在配置檔案中指定某個 Bean 的 qualifier 名字,方法如下:
 <bean id="person" class="footmark.spring.Person"> 
    <qualifier value="ppp"/> 
 </bean>
           

如果沒有明确指定 Bean 的 qualifier 名字,那麼預設名字就是 Bean 的名字。通常,qualifier 應該是有業務含義的,例如 "domain","persistent" 等,而不應該是類似 "person" 方式。

我們還可以将 @Qualifier 标注在集合類型上,那麼所有 qualifier 名字與指定值相同的 Bean 都将被注入進來。

最後,配置檔案中需要指定每一個自定義注解的屬性值。我們可以使用 <meta> 标簽來代替 <qualifier/> 标簽,如果 <meta> 标簽和 <qualifier/> 标簽同時出現,那麼優先使用 <qualifier> 标簽。如果沒有 <qualifier> 标簽,那麼會用 <meta> 提供的鍵值對來封裝 <qualifier> 标簽。示例如下:

<bean class="footmark.HelloWorld"> 
 <qualifier type="MovieQualifier"> 
 <attribute key="format" value="VHS"/> 
 <attribute key="genre" value="Comedy"/> 
 </qualifier> 
 </bean> 
 <bean class="footmark.HelloWorld"> 
 <meta key="format" value="DVD"/> 
 <meta key="genre" value="Action"/> 
 </bean>
           

@Autowired 注解對應的後處理注冊與前面相似,隻需在配置檔案中增加如下一行即可:

<context:annotation-config/>

如果 @Autowired 注入的是 BeanFactory、ApplicationContext、ResourceLoader 等系統類型,那麼則不需要 @Qualifier,此時即使提供了 @Qualifier 注解,也将會被忽略;而對于自定義類型的自動裝配,如果使用了 @Qualifier 注解并且沒有名字與之比對的 Bean,則自動裝配比對失敗。

@Autowired預設按類型裝配,預設情況下必須要求依賴對象必須存在,如果要允許null值,可以設定它的required屬性為false,例如:@Autowired(required=false)