Spring系列七:Spring 自動裝配

相思相見知何日?此時此夜難爲情。java

https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/spring/spring09.jpg

概述

Spring框架中,在配置文件中聲明bean的依賴關係是一個很好的作法,由於Spring容器可以自動裝配協做bean之間的關係。這稱爲spring自動裝配。git

自動裝配功能具備四種模式。分別是 nobyNamebyTypeconstructorgithub

已棄用另外一種自動連線模式自動檢測。Docsautodetect選項提供了太多的magic,最好使用更明確的聲明。spring

  • XML配置中的默認自動裝配模式爲no
  • Java配置中的默認自動裝配模式是byType

https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/spring/spring10.png

自動裝配模式

  1. no 該選項是spring框架的默認選項,表示自動裝配爲關閉狀態OFF。咱們必須在bean定義中使用<property>標籤顯式設置依賴項。
  2. byName 此選項啓用基於bean名稱的依賴項注入。在Bean中自動裝配屬性時,屬性名稱用於在配置文件中搜索匹配的Bean定義。若是找到這樣的bean,則將其注入屬性。若是找不到這樣的bean,則會引起錯誤。
  3. byType 此選項支持基於bean類型的依賴項注入。在bean中自動裝配屬性時,屬性的類類型用於在配置文件中搜索匹配的bean定義。若是找到這樣的bean,就在屬性中注入它。若是沒有找到這樣的bean,就會引起一個錯誤。
  4. 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進行自動裝配。ui

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進行自動裝配。this

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定義,這樣它們就不能經過自動裝配模式被注入,可使用設置爲falseautowire-candidate來作到這一點。

  1. 使用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>
  2. 另外一種方法是根據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屬性的值truefalse始終優先,而對於此類bean,模式匹配規則將不適用。

這就是Spring bean自動裝配的所有內容。


https://niocoder.com/assets/images/qrcode.jpg

🙂🙂🙂關注微信公衆號java乾貨 不按期分享乾貨資料

原文連接:Spring Bean Autowiring – @Autowired

相關文章
相關標籤/搜索