相思相見知何日?此時此夜難為情。
概述
在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干貨
不定期分享干貨資料



