Spring的IoC容器

  使用SpringIoC容器
3.1 BeanFactoryApplicationContext的介紹
3.1.1 BeanFactory介紹 BeanFactory是一個類工廠,但它和傳統的類工廠不一樣,傳統的類工廠僅生成一個類的對象,或幾個實現某一相同接口類的對象。而BeanFactory是通用的工廠,他能夠建立和管理各類類的對象。這些可被建立和管理的對象自己沒有什麼特別之處,僅是一個簡單的POJOSpring稱這些被建立和被管理的Java對象爲Bean。咱們知道JavaBean是要知足必定規範的,如必須提供一個默認不帶參的構造函數、不依賴於某一特定的容器等,但Spring中所說的BeanJavaBean更寬泛一些,因此不須要額外服務支持的POJO均可以是Bean
SpringBeanFactory提供了多種實現,最經常使用的是XmlBeanFactory。咱們該如何得到一個XmlBeanFactory呢?
代碼清單1
Resource resource = new FileSystemResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);

ClassPathResource resource = new ClassPathResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
代碼清單1中咱們經過FileSystemResourceClassPathResource都得到了XmlBeanFactory。可是咱們有了XmlBeanFactory對象又能幹什麼用呢?
代碼清單2
 
    public class Foo {
        private String name ;
        public void setName(String name) {
           this . name = name;
        }
        public String toStirng(){
           return "Foo Name is :" + this . name ;
        }
}
<? xml version = "1.0" encoding = "UTF-8" ?>
< beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:p = "http://www.springframework.org/schema/p" xmlns:context = "http://www.springframework.org/schema/context" xsi:schemaLocation = "
           [url]http://www.springframework.org/schema/beans[/url] [url]http://www.springframework.org/schema/beans/spring-beans-2.5.xsd[/url]
           [url]http://www.springframework.org/schema/context[/url] [url]http://www.springframework.org/schema/context/spring-context-2.5.xsd[/url]" >
    < bean id = "foo" class = "com.tony.test.Foo" >
       < property name = "name" value = "Foo" />
    </ bean >
</ beans >
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class Test {
    public static void main(String[] args) {
       // 定義 Spring 配置文件
       ClassPathResource resource = new
                     ClassPathResource( "spring-config-beans.xml" );
       // 實例化 BeanFactory
       BeanFactory factory = new XmlBeanFactory(resource);
        // 根據配置文件中的 id 得到 Bean
       Foo foo = (Foo) factory.getBean( "foo" );   
        System. out .println(foo.toStirng());   
    }  
}
運行結果 Foo Name is :Foo
代碼清單 2 中咱們首先定義了一個很普通的 java Foo.java 而後在 Spring 配置文件中將其配置 , 關鍵的是咱們的 Test.java 類咱們首先實例化了 ClassPathResource 對象,在實例化時咱們已經告訴了它 Spring 配置文件的名稱,實例化 BeanFactory 後咱們經過 factory.getBean 就能夠得到由 Spring 管理的 Bean 了。咱們驚奇的發現 Spring 居然幫咱們把 Foo 對象中 name 屬性的數據裝配進去了。
3.1.2 A pplicationContext 介紹 若是說 BeanFactory Spring 的心臟,那麼 ApplicationContext 就是 Spring 的五臟六腑和軀幹四肢了。 ApplicationContext 接口由 BeanFactory 派生而來,提供了更多面向實際應用的功能,在 BeanFactory 中,不少功能須要以編程的方式進行操做,而在 ApplicationContext 中則能夠經過配置的方式進行控制。 簡而言之,BeanFactory提供了配製框架及基本功能,而ApplicationContext則增長了更多支持企業核心內容的功能。ApplicationContext徹底由BeanFactory擴展而來,於是BeanFactory所具有的能力和行爲也適用於ApplicationContext
3.2 Bean的基本配置
       每一個bean都有一個或多個id(或稱之爲標識符或名稱,在術語上能夠理  解成    一回事)。這些id在當前IoC容器中必須惟一。若是一個bean有多   id      那麼其餘的id在本質上將被認爲是別名。
    當使用基於XML的配置元數據時,將經過idname屬性來指定bean標識        符。    id屬性具備惟一性,並且是一個真正的XML ID屬性,所以其餘xml    元素在引用該id時,能夠利用XML解析器的驗證功能。一般狀況下最好爲    bean指定一個id。儘管XML規範規定了XML ID命名的有效字符,可是bean  標識符的定義不受該限制,由於除了使用指定的XML字符來做爲id,還能夠    bean指定別名,要實現這一點能夠在name屬性中使用逗號、冒號或者空  格將多個id分隔。
    值得注意的是,爲一個bean提供一個name並非必須的,若是沒有指定,  那麼容器將爲其生成一個唯一的name
< bean id = "foo" class = "com.tony.test.Foo"/ >
通常狀況下, SpringIoC 容器中的一個 Bean 即對應配置文件中的一個 <bean> ,這種鏡像性的對應關係很容易理解。其中 id 爲這個 Bean 的名稱,經過容器的 getBean(「foo」) 便可獲取對應的 Bean ,在容器中起到定位查找的做用,是外部程序和 SpringIoC 容器進行通訊的橋樑。 Class 屬性指定了 Bean 對應的實現類。
3.3 依賴注入
Spring支持兩種依賴注入方式,分別是屬性注入和構造函數注入。。
3.3.1 屬性注入
屬性注入即經過setXxx()方法注入Bean的屬性值或依賴對象,因爲屬性注入方式具備可選擇性和靈活性高的優勢,所以屬性注入是實際應用中最經常使用的注入方式。
代碼清單1
    public class Foo {
        private String name ;
        public void setName(String name) {
           this . name = name;
        }
        public String toStirng(){
           return "Foo Name is :" + this . name ;
        }
}
    < bean id = "foo" class = "com.tony.test.Foo" >
       < property name = "name" value = "Foo" />
    </ bean >
Foo類中定義了一個屬性name,並提供了對應的Setter方法,咱們配置了一個Bean,併爲該Beanname屬性提供了屬性值。具體來講,Bean的每個屬性對應一個 <property> 標籤, name 爲屬性的名稱,在 Bean 實現類中擁有與其的對應的 Setter 方法 name 對應 setName() 方法。
3.3.2 構造函數注入
構造函數注入是除屬性注入以外的另外一種經常使用注入方式,它保證一些必要的屬性在 Bean 實例化時就獲得設置,它保證了 Bean 實例在實例化後就可使用。
代碼清單 1
    public class Foo {
        private String name ;
        private int age ;
        public Foo(String name, int age){
           this . name = name;
           this . age = age;
        }
        public String toStirng(){
           return "Foo Name is :" + this . name ;
        }
}
    < bean id = "foo" class = "com.tony.test.Foo" >
       < constructor-arg type = "int" >
           < value > 20 </ value >
       </ constructor-arg >
       < constructor-arg type = "java.lang.String" >
           < value > Foo </ value >
       </ constructor-arg >
</ bean >
代碼清單 1 中咱們定義了一個構造函數,接受一個 String 類型的入參,配置文件中咱們配別經過 <constructor-arg> 元素中定義了 type 類型爲 java.lang.String int 的兩個元素, Spring 會經過 type 類型來對構造函數進行注入,所以咱們在配置文件和構造函數入參順序不一樣的狀況下仍是能夠成功注入。可是咱們對於多個構造函數而且類型都同樣的時候咱們改怎麼辦呢?
代碼清單 2
< bean id = "foo" class = "com.tony.test.Foo" >
       < constructor-arg index = "0" value = "Foo" />
       < constructor-arg index = "1" value = "20" />
</ bean >
只要修改配置文件中 <constructor-arg> 元素把 type 屬性改成 index 而且指定參數的索引就可一了,這裏必定要注意索引是從 0 開始的。
3.4 Bean 的做用域
在配置文件中定義 Bean 時,用戶不單能夠配置 Bean 的屬性值以及相互之間的依賴關係,還能夠定義 Bean 的做用域。做用域將對 Bean 的生命週期和建立方式產生影響。在低版本的 Spring 中,僅有兩個做用域: singleton prototype ,在 Spring2.0 中,針對 WebApplicationContext 新增長了 3 個做用域。
singleton <bean id="foo" class="…" scope="singleton"/>
    SpringIoC 容器中僅存在一個 Bean 實例, Bean 以單實例的方式存在。
prototype <bean id="foo" class="…" scope="prototype"/>
    每次從容器中調用 Bean 時,都返回一個新的實例,即每次調用 getBean 時,至關於執行 newXxxBean 的操做。
request < bean id = "foo" class = "…" scope = " request " />
       每次HTTP請求都會建立一個新的Bean。該做用域僅適用於WebApplicationContext環境。
session   < bean id = "foo" class = "…" scope = " session " />
       同一個HTTPSession共享一個Bean,不一樣HTTPSession使用不一樣的Bean。該做用域僅適用於WebApplicationContext環境。
globalSession    < bean id = "foo" class = "…" scope = " globalSession " />
       同一個全局Session共享一個Bean,通常用於Protlet應用環境。該做用域僅適用於WebApplicationContext環境。
相關文章
相關標籤/搜索