Spring系列七:Spring 自動裝配


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

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

概述

Spring框架中,在配置文件中聲明bean的依賴關系是一個很好的做法,因為Spring容器能夠自動裝配協作bean之間的關系。這稱為spring自動裝配。

自動裝配功能具有四種模式。分別是 nobyNamebyTypeconstructor

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

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

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定義,這樣它們就不能通過自動裝配模式被注入,可以使用設置為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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM