@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)