相思相見知何日?此時此夜難為情。
概述
在Spring
框架中,在配置文件中聲明bean
的依賴關系是一個很好的做法,因為Spring
容器能夠自動裝配協作bean
之間的關系。這稱為spring
自動裝配。
自動裝配功能具有四種模式。分別是 no
,byName
,byType
和constructor
。
已棄用另一種自動連線模式自動檢測。
Docs
說autodetect
選項提供了太多的magic
,最好使用更明確的聲明。
XML
配置中的默認自動裝配模式為no
。Java
配置中的默認自動裝配模式是byType
。
自動裝配模式
no
該選項是spring
框架的默認選項,表示自動裝配為關閉狀態OFF
。我們必須在bean
定義中使用<property>
標簽顯式設置依賴項。byName
此選項啟用基於bean
名稱的依賴項注入。在Bean
中自動裝配屬性時,屬性名稱用於在配置文件中搜索匹配的Bean
定義。如果找到這樣的bean
,則將其注入屬性。如果找不到這樣的bean
,則會引發錯誤。byType
此選項支持基於bean
類型的依賴項注入。在bean
中自動裝配屬性時,屬性的類類型用於在配置文件中搜索匹配的bean
定義。如果找到這樣的bean
,就在屬性中注入它。如果沒有找到這樣的bean
,就會引發一個錯誤。constructor
通過構造函數自動裝配與byType
相似,僅適用於構造函數參數。在啟用了自動裝配的bean
中,它將查找構造函數參數的類類型,然后對所有構造函數參數執行自動裝配類型。請注意,如果容器中沒有一個完全屬於構造函數參數類型的bean
,則會引發致命錯誤。
@Autowired
注解
除了bean
配置文件中提供的自動裝配模式之外,還可以使用@Autowired
注解在bean
類中指定自動裝配。要在bean
類中使用@Autowired
自動注入,必須首先使用以下配置在spring
應用程序中啟用自動注入。
啟用注解配置
<context:annotation-config />
使用配置文件中的AutowiredAnnotationBeanPostProcessor
bean
定義可以實現相同的目的。
<bean class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
使用@Autowired
注解
現在,啟用注解配置后,可以隨意使用@Autowired
自動連接bean
依賴項。這可以通過三種方式完成:
@Autowired
屬性
在屬性上使用@Autowired
時,等效於在配置文件中通過byType
自動注入
public class EmployeeBean
{
@Autowired
private DepartmentBean departmentBean;
public DepartmentBean getDepartmentBean() {
return departmentBean;
}
public void setDepartmentBean(DepartmentBean departmentBean) {
this.departmentBean = departmentBean;
}
//More code
}
@Autowired
在屬性setter
方法上
在屬性的setter
方法上使用@Autowired
時,它也等效於在配置文件中通過byType
進行自動裝配。
public class EmployeeBean
{
private DepartmentBean departmentBean;
public DepartmentBean getDepartmentBean() {
return departmentBean;
}
@Autowired
public void setDepartmentBean(DepartmentBean departmentBean) {
this.departmentBean = departmentBean;
}
//More code
}
@Autowired
在構造函數上
在bean
的構造函數上使用@Autowired
時,它也等同於在配置文件中通過 constructor
進行自動裝配。
package cn.howtodoinjava.autowire.constructor;
public class EmployeeBean
{
@Autowired
public EmployeeBean(DepartmentBean departmentBean)
{
this.departmentBean = departmentBean;
}
private DepartmentBean departmentBean;
public DepartmentBean getDepartmentBean() {
return departmentBean;
}
public void setDepartmentBean(DepartmentBean departmentBean) {
this.departmentBean = departmentBean;
}
//More code
}
@Qualifier
解決沖突
我們了解到,如果我們在byType
模式下使用自動裝配,容器會在屬性類類型中查找依賴項。如果找不到這樣的類型,則會引發錯誤。但是,如果有兩個或多個相同類類型的bean
,該怎么辦?
在這種情況下,spring
將無法選擇正確的bean
來注入屬性,因此你將需要使用@Qualifier
注解來幫助容器。
要解析特定的bean
,我們需要使用@Qualifier
注解以及@Autowired
注解,並將bean
名稱傳遞到注解參數中。看看下面的例子:
public class EmployeeBean{
@Autowired
@Qualifier("finance")
private DepartmentBean departmentBean;
public DepartmentBean getDepartmentBean() {
return departmentBean;
}
public void setDepartmentBean(DepartmentBean departmentBean) {
this.departmentBean = departmentBean;
}
//More code
}
其中重復的bean
配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<context:annotation-config />
<bean id="employee" class="cn.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">
<property name="fullName" value="Lokesh Gupta"/>
</bean>
<!--First bean of type DepartmentBean-->
<bean id="humanResource" class="cn.howtodoinjava.autowire.constructor.DepartmentBean" >
<property name="name" value="Human Resource" />
</bean>
<!--Second bean of type DepartmentBean-->
<bean id="finance" class="cn.howtodoinjava.autowire.constructor.DepartmentBean" >
<property name="name" value="Finance" />
</bean>
</beans>
使用required = false
進行錯誤安全的自動裝配
即使在自動裝配Bean
依賴項時已格外小心,仍然可能會發現奇怪的查找失敗。因此,要解決此問題,您將需要使自動裝配成為可選的,以便在未找到依賴項的情況下,應用程序不應引發任何異常,而自動裝配應被忽略。
這可以通過兩種方式完成:
- 如果要使特定的
bean
屬性的非強制性的特定bean
自動裝配,可以在@Autowired
注解中使用required =“ false”
屬性。@Autowired (required=false) @Qualifier ("finance") private DepartmentBean departmentBean;`
- 如果要在全局級別(即對所有
bean
中的所有屬性)應用可選的自動裝配;使用以下配置設置。<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"> <property name="requiredParameterValue" value="false" /> </bean>
從自動裝配中排除bean
默認情況下,自動裝配掃描並匹配范圍內的所有bean
定義。如果您想排除一些bean
定義,這樣它們就不能通過自動裝配模式被注入,可以使用設置為false
的autowire-candidate
來做到這一點。
- 使用
autowire-candidate
作為false
完全將bean
排除在自動裝配候選之外。它將特定的bean
定義完全排除在自動裝配基礎結構之外。<?xml version="1.0" encoding="UTF-8"?> <beans> <context:annotation-config /> <bean id="employee" class="cn.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor"> <property name="fullName" value="Lokesh Gupta"/> </bean> <!--Will be available for autowiring--> <bean id="humanResource" class="cn.howtodoinjava.autowire.constructor.DepartmentBean" > <property name="name" value="Human Resource" /> </bean> <!--Will not participate in autowiring--> <bean id="finance" class="cn.howtodoinjava.autowire.constructor.DepartmentBean" autowire-candidate="false"> <property name="name" value="Finance" /> </bean> </beans>
- 另一種方法是根據
bean
名稱的模式匹配來限制自動裝配候選對象。頂級<beans/>
元素在其default-autowire-candidate
屬性中接受一個或多個屬性。
例如,要將自動裝配候選狀態限制為名稱以Impl
結尾的任何bean
,請提供值* Impl
。要提供多種模式,請在以逗號分隔的列表中定義它們。<?xml version="1.0" encoding="UTF-8"?> <beans default-autowire-candidates="*Impl,*Dao"> <context:annotation-config /> <bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor"> <property name="fullName" value="Lokesh Gupta"/> </bean> <!--Will be available for autowiring--> <bean id="humanResource" class="com.howtodoinjava.autowire.constructor.DepartmentBean" > <property name="name" value="Human Resource" /> </bean> <!--Will not participate in autowiring--> <bean id="finance" class="com.howtodoinjava.autowire.constructor.DepartmentBean" autowire-candidate="false"> <property name="name" value="Finance" /> </bean> </beans>
請注意,bean
定義的autowire-candidate
屬性的值true
或false
始終優先,而對於此類bean
,模式匹配規則將不適用。
這就是Spring
bean
自動裝配的全部內容。
🙂🙂🙂關注微信公眾號java干貨
不定期分享干貨資料