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文件。
 
public class HelloBean {  

    private String helloWord; 

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

}

xml文件:

<?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="helloBean"  
          class="onlyfun.caterpillar.HelloBean">  
        <property name="helloWord"> 
            <value>Hello!Justin!</value> 
        </property>  
    </bean>  
</beans>

java:

public class SpringDemo {  
    public static void main(String[] args) {  
        Resource rs = new FileSystemResource("beans-config.xml");  
        BeanFactory factory = new XmlBeanFactory(rs);  
         
        HelloBean hello = (HelloBean) factory.getBean("helloBean");  
        System.out.println(hello.getHelloWord());  
    }  
}
二、使用constructor方式完成注入
其中xml配置有如下方式:
在配置文件中配置該類的bean,並配置構造器,在配置構造器中用到了<constructor-arg>節點,該節點有四個屬性:

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

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

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

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

 java代碼:
public class HelloBean { 
    private String name; 
    private String helloWord; 

    // 建議有要無參數建構方法 
    public HelloBean() { 
    } 
     
    public HelloBean(String name, String helloWord) { 
        this.name = name; 
        this.helloWord = helloWord; 
    } 

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

xml文件:

<?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="helloBean"  
          class="onlyfun.caterpillar.HelloBean">  
        <constructor-arg index="0"> 
            <value>Justin</value> 
        </constructor-arg>  
        <constructor-arg index="1"> 
            <value>Hello</value> 
        </constructor-arg>  
    </bean>  
</beans>

java代碼:

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("Name: "); 
        System.out.println(hello.getName()); 
        System.out.print("Word: "); 
        System.out.println(hello.getHelloWord());  
    }  
}

 

三、屬性參考
 
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" />  
         </ property >  
     </ 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屬性的按類型自動綁定。
 
< beans >  
     < bean  id ="dateBean"  class ="java.util.Date" />  
     < bean  id ="helloBean"  class ="onlyfun.caterpillar.HelloBean"  autowire ="byType" >  
         < property  name ="helloWord" >  
             < value >Hello! </ value >  
         </ property >  
     </ bean >  
</ beans >
 
五、“byName”自動綁定
 
將“三”中的配置文件改為下面,即可完成bean屬性的按名稱自動綁定。
 
< beans >  
     < bean  id ="dateBean"  class ="java.util.Date" />  
     < bean  id ="helloBean"  class ="onlyfun.caterpillar.HelloBean"  autowire ="byName" >  
         < property  name ="helloWord" >  
             < value >Hello! </ value >  
         </ property >  
     </ bean >  
</ beans >
 
六、“constructor”自動綁定
 
將“三”中的配置文件改為下面,即可完成bean屬性的按構造方法自動綁定。在建立依賴關系時,Srping容器會試圖比對容器中的Bean實例類型,及相關的構造方法上的參數類型,看看在類型上是否符合,如果有的話,則選用該構造方法來建立Bean實例。如果無法綁定,則拋出org.springframework.beans.factory.UnsatisfiedDependencyException異常。
 
< beans >  
     < bean  id ="dateBean"  class ="java.util.Date" />  
     < bean  id ="helloBean"  class ="onlyfun.caterpillar.HelloBean"  autowire ="constructor" >  
         < property  name ="helloWord" >  
             < value >Hello! </ value >  
         </ property >  
     </ bean >  
</ beans >
 
七、“autodetect”自動綁定
 
將“三”中的配置文件改為下面,即可完成bean屬性的自動綁定,這個自動綁定是Spring會嘗試用入constructor來處理依賴關系的建立,如果不行,則再嘗試用byType類建立依賴關系。
 
< beans >  
     < bean  id ="dateBean"  class ="java.util.Date" />  
     < bean  id ="helloBean"  class ="onlyfun.caterpillar.HelloBean"  autowire ="autodetect" >  
         < property  name ="helloWord" >  
             < value >Hello! </ value >  
         </ property >  
     </ bean >  
</ beans >
 
八、依賴檢查方式
 
在自動綁定中,由於沒辦法從定義文件中,清楚地看到是否每個屬性都完成設定,為了確定某些依賴關系確實建立,您可以假如依賴檢查,在<bean>標簽使用時設定"dependency-check",可以有四種依賴檢查方式:simple、objects、all、none。
 
simple:只檢查簡單的類型(像原生數據類型或字符串對象)屬性是否完成依賴關系,。
objects:檢查對象類型的屬性是否完成依賴關系。
all:則檢查全部的屬性是否完成依賴關系。
none:設定是默認值,表示不檢查依賴性。
 
< beans >  
     < bean  id ="dateBean"  class ="java.util.Date" />  
     < bean  id ="helloBean"  class ="onlyfun.caterpillar.HelloBean"  autowire ="autodetect"  dependeny-check ="all" >  
         < property  name ="helloWord" >  
             < value >Hello! </ value >  
         </ property >  
     </ bean >  
</ beans >
 
九、集合對象注入
 
對於像數組、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() { 
         return name; 
    } 
}
 
<? 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" > 
         < property  name ="name" > 
             < value >momor </ value > 
         </ property > 
     </ bean > 
     
     < bean  id ="someBean"  class ="onlyfun.caterpillar.SomeBean" > 
         < property  name ="someStrArray" > 
             < list > 
                 < value >Hello </ value > 
                 < value >Welcome </ value > 
             </ list > 
         </ property > 
         
         < property  name ="someObjArray" > 
             < list > 
                  < ref  bean ="some1" /> 
                  < ref  bean ="some2" /> 
             </ list > 
         </ property > 
         
         < property  name ="someList" > 
             < list > 
                  < value >ListTest </ value > 
                  < ref  bean ="some1" /> 
                  < ref  bean ="some2" /> 
             </ list > 
         </ property > 
         
         < property  name ="someMap" > 
             < map > 
                  < entry  key ="MapTest" > 
                      < value >Hello!Justin! </ value > 
                  </ entry > 
                  < entry  key ="someKey1" > 
                      < ref  bean ="some1" /> 
                  </ entry > 
             </ map > 
         </ property > 
     </ bean >  
</ beans >
 
public  class SpringDemo {  
     public  static  void main(String[] args) {  
        ApplicationContext context =  
             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型態依賴注入對象 
        System.out.println(); 
        Map someMap = (Map) someBean.getSomeMap(); 
        System.out.println(someMap.get( "MapTest")); 
        System.out.println(someMap.get( "someKey1")); 
    }  
}
 

十、靜態工廠的方法注入

靜態工廠顧名思義,就是通過調用靜態工廠的方法來獲取自己需要的對象,為了讓spring管理所有對象,我們不能直接通過"工程類.靜態方法()"來獲取對象,而是依然通過spring注入的形式獲取:
Java代碼 
    package com.bless.springdemo.factory;  
      
    import com.bless.springdemo.dao.FactoryDao;  
    import com.bless.springdemo.dao.impl.FactoryDaoImpl;  
    import com.bless.springdemo.dao.impl.StaticFacotryDaoImpl;  
      
    public class DaoFactory {  
        //靜態工廠  
        public static final FactoryDao getStaticFactoryDaoImpl(){  
            return new StaticFacotryDaoImpl();  
        }  
    }  
同樣看關鍵類,這里我需要注入一個FactoryDao對象,這里看起來跟第一種注入一模一樣,但是看隨后的xml會發現有很大差別:
Java代碼
public class SpringAction {  
        //注入對象  
    private FactoryDao staticFactoryDao;  
      
    public void staticFactoryOk(){  
        staticFactoryDao.saveFactory();  
    }  
    //注入對象的set方法  
    public void setStaticFactoryDao(FactoryDao staticFactoryDao) {  
        this.staticFactoryDao = staticFactoryDao;  
    }  
}  
Spring的IOC配置文件,注意看<bean name="staticFactoryDao">指向的class並不是FactoryDao的實現類,而是指向靜態工廠DaoFactory,並且配置 factory-method="getStaticFactoryDaoImpl"指定調用哪個工廠方法:
Xml代碼
<!--配置bean,配置后該類由spring管理-->  
    <bean name="springAction" class="com.bless.springdemo.action.SpringAction" >  
        <!--(3)使用靜態工廠的方法注入對象,對應下面的配置文件(3)-->  
        <property name="staticFactoryDao" ref="staticFactoryDao"></property>  
                </property>  
    </bean>  
    <!--(3)此處獲取對象的方式是從工廠類中獲取靜態方法-->  
    <bean name="staticFactoryDao" class="com.bless.springdemo.factory.DaoFactory" factory-method="getStaticFactoryDaoImpl"></bean>

十一、實例工廠的方法注入

實例工廠的意思是獲取對象實例的方法不是靜態的,所以你需要首先new工廠類,再調用普通的實例方法:
Java代碼
public class DaoFactory {  
    //實例工廠  
    public FactoryDao getFactoryDaoImpl(){  
        return new FactoryDaoImpl();  
    }  
} 
那么下面這個類沒什么說的,跟前面也很相似,但是我們需要通過實例工廠類創建FactoryDao對象:
Java代碼 
public class SpringAction {  
    //注入對象  
    private FactoryDao factoryDao;  
      
    public void factoryOk(){  
        factoryDao.saveFactory();  
    }  
  
    public void setFactoryDao(FactoryDao factoryDao) {  
        this.factoryDao = factoryDao;  
    }  
} 
最后看spring配置文件:
Xml代碼
    <!--配置bean,配置后該類由spring管理-->  
        <bean name="springAction" class="com.bless.springdemo.action.SpringAction">  
            <!--(4)使用實例工廠的方法注入對象,對應下面的配置文件(4)-->  
            <property name="factoryDao" ref="factoryDao"></property>  
        </bean>  
          
        <!--(4)此處獲取對象的方式是從工廠類中獲取實例方法-->  
        <bean name="daoFactory" class="com.bless.springdemo.factory.DaoFactory"></bean>  
        <bean name="factoryDao" factory-bean="daoFactory" factory-method="getFactoryDaoImpl"></bean>  

 

 
 


免責聲明!

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



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