天天看點

Spring Bean基本管理--bean注入方式彙總

依賴注入方式:Spring支援兩種依賴注入方式,分别是屬性注入和構造函數注入。還有工廠方法注入方式。

依賴注入還分為:注入依賴對象可以采用手工裝配或自動裝配,在實際應用開發中建議使用手工裝配,因為自動裝配會産生許多未知情況,開發人員無法預見最終的裝配結果。

手工裝配依賴對象又分為3種方式:

1、程式設計方式(寫的過程中向BeanFactory去注冊)

2、是在XML檔案中,通過在bean節點下配置;如上面講到的使用屬性的setter方法注入依賴對象和使用構造器方法注入依賴對象都是這種方式。

3、就是在java代碼中使用注解的方式進行裝配,在代碼中加入@Resource或者@Autowired等,怎樣使用注解的方式來為某個bena注入依賴對象呢?

自動裝配依賴對象分為2種方式:

1、配置檔案的bean中增加autowire

2、也可以選擇在beans中加入default-autowire屬性,為所有bean設定預設自動裝配

Spring中提供了自動裝配依賴對象的機制,但是在實際應用中并不推薦使用自動裝配,因為自動裝配會産生未知情況,開發人員無法預見最終的裝配結果。

自動裝配是在配置檔案中實作的,如下:

<bean id="***" class="***" autowire="byType">

隻需要配置一個autowire屬性即可完成自動裝配,不用再配置檔案中寫<property>,但是在類中還是要生成依賴對象的setter方法。

Autowire的屬性值有如下幾個:

· byType 按類型裝配  可以根據屬性類型,在容器中尋找該類型比對的bean,如有多個,則會抛出異常,如果沒有找到,則屬性值為null;

· byName 按名稱裝配  可以根據屬性的名稱在容器中查詢與該屬性名稱相同的bean,如果沒有找到,則屬性值為null;

· constructor 與byType方式相似,不同之處在與它應用于構造器參數,如果在容器中沒有找到與構造器參數類型一緻的bean,那麼将抛出異常;

· autodetect 通過bean類的自省機制(introspection)來決定是使用constructor還是byType的方式進行自動裝配。如果發現預設的構造器,那麼将使用byType的方式。

---------------分割線-----------------------------------------------------------------------------------------------------

示例:

一、使用屬性setter方法注入

下面是Bean和beans-config.xml檔案。

xml檔案:

java:

二、使用constructor方式完成注入

其中xml配置有如下方式:

在配置檔案中配置該類的bean,并配置構造器,在配置構造器中用到了<constructor-arg>節點,該節點有四個屬性:

· index是索引,指定注入的屬性,從0開始,如:0代表personDao,1代表str屬性;

· type是指該屬性所對應的類型,如Persondao對應的是com.aptech.dao.PersonDAO;

· ref 是指引用的依賴對象;

· value 當注入的不是依賴對象,而是基本資料類型時,就用value;

 java代碼:

java代碼:

三、屬性參考

public class HelloBean {  

    private String helloWord;  

    private Date date;  

    //...省略getter、setter方法     

}

<beans>  

    <bean id="dateBean" class="java.util.Date"/>  

    <bean id="helloBean" class="onlyfun.caterpillar.HelloBean">  

        <property name="helloWord">  

            <value>Hello!</value>  

        </property>  

        <property name="date">  

            <ref bean="dateBean"/>  

    </bean>  

</beans>

public class SpringDemo {  

    public static void main(String[] args) {  

        ApplicationContext context =  

            new FileSystemXmlApplicationContext("beans-config.xml"); 

        HelloBean hello = (HelloBean) context.getBean("helloBean"); 

        System.out.print(hello.getHelloWord()); 

        System.out.print(" It's "); 

        System.out.print(hello.getDate()); 

        System.out.println("."); 

    }  

四、“byType”自動綁定

将“三”中的配置檔案改為下面,即可完成bean屬性的按類型自動綁定。

    <bean id="helloBean" class="onlyfun.caterpillar.HelloBean" autowire="byType">  

五、“byName”自動綁定

将“三”中的配置檔案改為下面,即可完成bean屬性的按名稱自動綁定。

    <bean id="helloBean" class="onlyfun.caterpillar.HelloBean" autowire="byName">  

六、“constructor”自動綁定

将“三”中的配置檔案改為下面,即可完成bean屬性的按構造方法自動綁定。在建立依賴關系時,Srping容器會試圖比對容器中的Bean執行個體類型,及相關的構造方法上的參數類型,看看在類型上是否符合,如果有的話,則選用該構造方法來建立Bean執行個體。如果無法綁定,則抛出org.springframework.beans.factory.UnsatisfiedDependencyException異常。

    <bean id="helloBean" class="onlyfun.caterpillar.HelloBean" autowire="constructor">  

七、“autodetect”自動綁定

将“三”中的配置檔案改為下面,即可完成bean屬性的自動綁定,這個自動綁定是Spring會嘗試用入constructor來處理依賴關系的建立,如果不行,則再嘗試用byType類建立依賴關系。

    <bean id="helloBean" class="onlyfun.caterpillar.HelloBean" autowire="autodetect">  

八、依賴檢查方式

在自動綁定中,由于沒辦法從定義檔案中,清楚地看到是否每個屬性都完成設定,為了确定某些依賴關系确實建立,您可以假如依賴檢查,在<bean>标簽使用時設定"dependency-check",可以有四種依賴檢查方式:simple、objects、all、none。

simple:隻檢查簡單的類型(像原生資料類型或字元串對象)屬性是否完成依賴關系,。

objects:檢查對象類型的屬性是否完成依賴關系。

all:則檢查全部的屬性是否完成依賴關系。

none:設定是預設值,表示不檢查依賴性。

    <bean id="helloBean" class="onlyfun.caterpillar.HelloBean" autowire="autodetect" dependeny-check="all">  

九、集合對象注入

對于像數組、List、Set、Map等集合對象,在注入前必須填充一些對象至集合中,然後再将集合對象注入至所需的Bean時,也可以交由Spring的IoC容器來自動維護或生成集合對象,并完成依賴注入。

public class SomeBean { 

    private String[] someStrArray; 

    private Some[] someObjArray; 

    private List someList; 

    private Map someMap; 

    public String[] getSomeStrArray() { 

        return someStrArray; 

    } 

    public void setSomeStrArray(String[] someStrArray) { 

        this.someStrArray = someStrArray; 

    public Some[] getSomeObjArray() { 

        return someObjArray; 

    public void setSomeObjArray(Some[] someObjArray) { 

        this.someObjArray = someObjArray; 

    public List getSomeList() { 

        return someList; 

    public void setSomeList(List someList) { 

        this.someList = someList; 

    public Map getSomeMap() { 

        return someMap; 

    public void setSomeMap(Map someMap) { 

        this.someMap = someMap; 

public class Some { 

    private String name; 

    public String getName() { 

        return name; 

    public void setName(String name) { 

        this.name = name; 

    public String toString() { 

<?xml version="1.0" encoding="UTF-8"?>  

<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"  

  "http://www.springframework.org/dtd/spring-beans.dtd">  

<beans> 

    <bean id="some1" class="onlyfun.caterpillar.Some"> 

        <property name="name"> 

            <value>Justin</value> 

        </property> 

    </bean> 

    <bean id="some2" class="onlyfun.caterpillar.Some"> 

            <value>momor</value> 

    <bean id="someBean" class="onlyfun.caterpillar.SomeBean"> 

        <property name="someStrArray"> 

            <list> 

                <value>Hello</value> 

                <value>Welcome</value> 

            </list> 

        <property name="someObjArray"> 

                 <ref bean="some1"/> 

                 <ref bean="some2"/> 

        <property name="someList"> 

                 <value>ListTest</value> 

        <property name="someMap"> 

            <map> 

                 <entry key="MapTest"> 

                     <value>Hello!Justin!</value> 

                 </entry> 

                 <entry key="someKey1"> 

                     <ref bean="some1"/> 

            </map> 

            new FileSystemXmlApplicationContext( 

                    "beans-config.xml"); 

        SomeBean someBean =  

            (SomeBean) context.getBean("someBean"); 

        // 取得數組型态依賴注入對象 

        String[] strs =  

            (String[]) someBean.getSomeStrArray(); 

        Some[] somes =  

            (Some[]) someBean.getSomeObjArray(); 

        for(int i = 0; i < strs.length; i++) { 

            System.out.println(strs[i] + ","  

                    + somes[i].getName()); 

        } 

        // 取得List型态依賴注入對象 

        System.out.println(); 

        List someList = (List) someBean.getSomeList();  

        for(int i = 0; i < someList.size(); i++) { 

            System.out.println(someList.get(i)); 

        // 取得Map型态依賴注入對象 

        Map someMap = (Map) someBean.getSomeMap(); 

        System.out.println(someMap.get("MapTest")); 

        System.out.println(someMap.get("someKey1")); 

十、靜态工廠的方法注入

靜态工廠顧名思義,就是通過調用靜态工廠的方法來擷取自己需要的對象,為了讓spring管理所有對象,我們不能直接通過"工程類.靜态方法()"來擷取對象,而是依然通過spring注入的形式擷取:

Java代碼 

同樣看關鍵類,這裡我需要注入一個FactoryDao對象,這裡看起來跟第一種注入一模一樣,但是看随後的xml會發現有很大差别:

Java代碼

Spring的IOC配置檔案,注意看<bean name="staticFactoryDao">指向的class并不是FactoryDao的實作類,而是指向靜态工廠DaoFactory,并且配置 factory-method="getStaticFactoryDaoImpl"指定調用哪個工廠方法:

Xml代碼

十一、執行個體工廠的方法注入

執行個體工廠的意思是擷取對象執行個體的方法不是靜态的,是以你需要首先new工廠類,再調用普通的執行個體方法:

那麼下面這個類沒什麼說的,跟前面也很相似,但是我們需要通過執行個體工廠類建立FactoryDao對象:

最後看spring配置檔案: