程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> Spring之依賴配置詳解

Spring之依賴配置詳解

編輯:關於C++

通過以上的學習,對spring容器和DI的概念應該比較清晰了,DI(依賴注入)作為spring的核心,spring當然提供了一套完善的機制來進行依賴注入。前篇文章從概念上介紹了依賴注入,本篇著重學習spring依賴注入的方法,這裡主要采用xml的方式。

基本注入

構造器注入和設值注入是依賴注入的兩種主要方式,spring對此有很完善的實現,下面首先以代碼的形式進行簡要的說明。

構造器注入

Spring容器通過調用bean的構造函數(可能帶有幾個參數,每個參數代表一個依賴)完成構造器注入。通過靜態工廠方法和調用構造器及其類似,這裡一並進行說明。

Spring中構造器依賴注入采用以下的形式,每個參數用bean標簽的子標簽 < constructor-arg >進行配置:

    
       
.. .. ..
    

Index:在構造函數中參數的位置,從0開始標簽中的配置包含5個項,使用他們中的某些進行某個依賴的配置,簡單的描述如下:

Value:參數值,通常是基本類型和 type或者index配合使用。

Name:構造函數中參數的名字

Ref:引用其他Spring管理的對象

Type:參數的類型,值為基本類型或者完全限定的類名。

基本Bean

下面采用代碼加注釋的形式分別對以上的配置項加以說明,引用的類庫見以前的文章,首先是簡單的代碼結構截圖:

\

Fruit

Apple、Banana是用來演示ref配置項的,只是一個簡單的類,沒有任何字段。Fruit包含一個Apple和一個Banana,其代碼如下:

package com.test.wdi;
 
 
/**  
* @date 2015-2-27
* @Description:此類主要是為了說明構造器注入的ref項,包含了基本的構造函數,靜態工廠方法,和實例工廠方法
*/
 
public class Fruit {
 
    private Apple apple;
   
    private Banana banana;
   
   
    public Fruit() {
       super();
    }
 
   
    /**  
    * 靜態工廠方法
    */
    public static Fruit newInstance(Apple apple, Banana banana){
       return new Fruit(apple, banana);
    }
   
    /**  
    * 實例工廠方法
    */
    public Fruit  newInstance1(Apple apple, Banana banana){
       return new Fruit(apple, banana);
    }
   
    /**  
    * 傳統帶參構造函數
    */
    public Fruit(Apple apple, Banana banana) {
       super();
       this.apple = apple;
       this.banana = banana;
    }
 
    public Apple getApple() {
       return apple;
    }
 
    public void setApple(Apple apple) {
       this.apple = apple;
    }
 
    public Banana getBanana() {
       return banana;
    }
 
    public void setBanana(Banana banana) {
       this.banana = banana;
    }
 
    @Override
    public String toString() {
       return hashCode()+ "Fruit [apple=" + apple + ", banana=" + banana + "]";
    }
   
}

ExampleBean

ExampleBean是用來演示除ref之外的其他配置項的,它有連個基本類型的字段,其代碼如下:

package com.test.wdi;
 
/**  
* @date 2015-2-28
* @Description:此類用來說明構造器注入配置項中的 name index type value的,為了方便重寫了toString方法
*/
public class ExampleBean {
 
    private int years;
    private String ultimateAnswer;
   
    private boolean test;
   
  
    public ExampleBean() {
       super();
    }
 
    /**
     * 構造函數2,和構造函數1一樣具有兩個參數,如果bean配置中不加入type的限制,
     * 將會有和預期不一致的結果
     */
    public ExampleBean(int years, boolean test) {
        this.years = years;
        this.test = test;
    }
   
   
    /**
     * 構造函數1
     */
    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
   
   
 
    @Override
    public String toString() {
       return "ExampleBean [years=" + years + ", ultimateAnswer=" + ultimateAnswer + ", test=" + test + "]";
    }
 
   
}

BeanXMl配置

Bean的配置,將依次說明標簽中每個配置屬性的簡單用法和它們的組合。bean配置包含連個文件,allbean.xml是主配置文件,它通過import標簽引入t1.xml,而t1.xml包含了所有的配置信息,且有詳細的注釋:



 
    
   
   
    
    
   
   



 
    
    
    
       
   
    
    
    
    
       
       
    
   
    
    
       
       
    
    
    
       
       
    
   
    
    
       
       
    
    
       
       
    
   
    
    
       
       
    
    
    
        
       
    
    
   
    
        
       
    

測試程序

測試程序使用main函數,依次打印出來t1中定義的那些bean,代碼如下:

package com.test;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
/**  
 * @Description:
 * 本示例例環境為eclipse
 */
public class TestMain {
    public static void main(String[] args) {
       /**
        * ApplicationContext代表spring容器,而ClassPathXmlApplicationContext是它的一個實現,它從類路徑下讀取相應的
        *  xml 元數據配置,並初始化容器。其中allbean.xml是相應的元數據配置
        */
       ApplicationContext context = new ClassPathXmlApplicationContext("allbean.xml");
      
       //依次打印對象
       System.out.println(context.getBean("f1"));
       System.out.println(context.getBean("f2"));
       System.out.println(context.getBean("f3"));
 
      
       System.out.println(context.getBean("exam1a"));
       System.out.println(context.getBean("exam1b"));
 
       System.out.println(context.getBean("exam2"));
       System.out.println(context.getBean("exam3"));
       System.out.println(context.getBean("exam4"));
 
    }
 
}

測試結果如下截圖,均符合預期:

\

<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+16Kjurm51OzG99ei0uLQ6NKq16LS4tGtu7fSwMC1tcTOyszioaM8L3A+CjxoMj7J6CYjMjA1NDA716LI6zwvaDI+CjxwPsnoJiMyMDU0MDvXosjrysdzcHJpbmfI3cb31Nq199PDuf3O3rLOubnU7Lqvyv278tXfzt6yzrmks6e3vbeouvOjrMi7uvPNqLn9tffTw8bkc2V0dGVyt723qL340NDSwMC1tcTXosjroaM8L3A+CjxwPlNldNeiyOuxyL3PvPK1paOs1q7HsLXEzsTVwnNwcmluZ8jdxve6zcXk1sOz9cq2y/m+2bXEwP3X077NysdzZXR0ZXLXosjroaPPwsPmysfSu7bOeG1sxeTWw7yrxuTLtcP3o7o8L3A+CjxwPjwvcD4KPHByZSBjbGFzcz0="brush:java;">

依賴注入實例

依賴有多種類型,包含基本類型(int、double、string等)和復雜類型(系統類和自定義的類),下面依次說明它們在注入過程中需要注意的問題。

設置注入和構造器注入對應的標簽分別是它們的子標簽的意義保持一致,下面的例子一般情況下,只做其中一種的說明。另外它們的屬性除了 單獨擁有的type和 index 其他的也保持一致的意義。

直接類型(原始類型、字符串等)

直接類型直接使用value子標簽或者屬性配置即可。Spring的conversion service 會自動把字符串轉化為真正的屬性(屬性或者構造函數參數)。

對應設置注入,由javabean規范和name屬性可以准確的確定類型,故轉換不存在問題。但是對於構造器注入,如果不對type或者name進行限制,可能會產生非預期結果。

如下一段配置實是上文中構造器中的一個片段,另外增加了設置注入加以比較。運行結果可以自行測試:


   
 
    
       
       
    
    
       
       
    
    
   
    
       
       
       
    


另外類型為java.util.properties可以采用類似下面的配置:


 
    
    
        
            jdbc.driver.className=com.mysql.jdbc.Driver
            jdbc.url=jdbc:mysql://localhost:3306/mydb
        
    

Idref標簽

Idref子標簽只是一個把某個bean的id傳遞作為依賴傳遞給另外一個bean的防止錯誤的方式。通過只傳遞bean的id,可以構建構建更加靈活的程序。

基本的配置如下:


    
        
        
            
        
    
    
        
         
        
    

引用其他bean

引用其他bean是spring中及其常見的場景,這種配置通過 的子標簽實現,或者通過ref屬性(實質上是子標簽的一種縮寫)。而子標簽的形式提供了更具體的用法和配置。

基本樣式如下:

或者

以上兩者的區別是:前者在當前spring容器和父容器中尋找id(name)為someBean 的對象,而後者只在父容器中尋找。

而ref屬性是前者的簡寫。

下面看具體的例子:



    
       
           
       
       
           
       
    
    
       
       
       
    

內部bean

內部定義的bean稱之為內部bean,spring會自動忽略其id、name 屬性和 scope屬性,配置如下:


    
       
           
       
       
           
 
       
    

集合

Java的強大之處之一在於jdk提供了強大的集合框架,spring當然提供了注入集合的方法。

自從java1.5開始,支持泛型,我們的集合盡量使用泛型,另外關於集合合並涉及到bean定義的繼承,這裡暫不討論。

首先引入一個帶集合屬性的bean,省略了構造函數和get set方法。

public class FruitCollection {
 
    private Set fruits;
    private List fruitList;
 
    private Map fruitMap;
   
    private Properties ppp;
}

具體見下面的配置代碼:


    
       
           
           
              
                  
                  
                  
              
              
              
              
              
              
              
              
           
       
 
       
                   
           
              
                  
                  
                  
              
              
              
              
              
              
              
              
           
       
 
       
           
           
              
              
              
              
           
       
 
       
          
           
          
           
              t1
              t2
              t3
              t4
           
       
    

Null和空串

Spring支持注入null和字符串的空串,見如下的配置:


    
        
       
           
       
       
    
   
    
         
       
       
       
    

實際相當於分別執行了如下方法:

setUltimateAnswer(null);
setUltimateAnswer("");

縮寫

Spring的bean配置文件的格式除了以上用了多次的標准形式,還有一些簡單的縮略形式,這些縮略形式是基於xml命名空間,分別是p-nameplace和c-nameplace,依次對應seter注入和 構造器注入。

這裡不再贅述。直接貼一個spring官方文檔的示例來說明p命名空間:


 
    
        
    
 
    

復合屬性名

嵌套的注入,fruit 有個apple屬性,假設apple 有個 color屬性。那麼可以在fruit的定義中直接為color注入屬性,前提是apple不為null:

    
    
        
        
    

結束

本文從spring兩種依賴注入講起,然後舉出具體的配置例子依次講解到了大部門的注入實例,本文中大部分的例子均通過測試,環境為spring4.1.5。但本人水平有限,肯定有很多不當和不完整支持,期待共同進步,本文中的實例用到的代碼地址為:本文資源下載地址(免積分)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved