Spring Framework 參考文檔(Bean概述)

Bean概述

Spring IoC容器管理一個或多個bean,這些bean是使用你提供給容器的配置元數據建立的(例如,以XML <bean/>定義的形式)。java

在容器內部,這些bean定義被表示爲BeanDefinition對象,其中包含(其餘信息)如下元數據:spring

  • 包限定的類名:一般,定義bean的實際實現類。
  • Bean行爲配置元素,它聲明Bean在容器中的行爲(做用域、生命週期回調,等等)。
  • 對bean執行其工做所需的其餘bean的引用,這些引用也稱爲協做者或依賴項。
  • 要在新建立的對象中設置的其餘配置設置 — 例如,池的大小限制或在管理鏈接池的bean中使用的鏈接數。

此元數據轉換爲組成每一個bean定義的一組屬性,下表描述了這些屬性:segmentfault

屬性 解釋
Class 實例化Bean
Name 命名Bean
Scope Bean做用域
構造函數參數 依賴注入
屬性 依賴注入
自動裝配模式 自動裝配協做者
延遲初始化模式 延遲初始化Bean
初始化方法 初始化回調
銷燬方法 銷燬回調

除了包含關於如何建立特定bean的信息的bean定義以外,ApplicationContext實現還容許註冊(由用戶)在容器外部建立的現有對象,經過getBeanFactory()方法訪問ApplicationContextBeanFactory,該方法返回BeanFactory DefaultListableBeanFactory實現。DefaultListableBeanFactory經過registerSingleton(..)registerBeanDefinition(..)方法支持這種註冊,然而,典型的應用程序只使用經過常規bean定義元數據定義的bean。api

Bean元數據和手動提供的單例實例須要儘早註冊,以便容器在自動裝配和其餘內省步驟中正確地推斷它們,雖然在某種程度上支持覆蓋現有的元數據和現有的單例實例,可是在運行時註冊新bean(與對工廠的實時訪問同時進行)並非官方支持的,而且可能會致使併發訪問異常、bean容器中不一致的狀態,或者二者兼有。

命名Bean

每一個bean都有一個或多個標識符,這些標識符在承載bean的容器中必須是唯一的,bean一般只有一個標識符,可是,若是須要多個,則能夠將額外的標識符視爲別名。併發

在基於XML的配置元數據中,可使用id屬性、name屬性或二者都使用來指定bean標識符,id屬性容許你精確地指定一個id,一般,這些名稱是字母數字('myBean'、'someService'等),但它們也能夠包含特殊字符。若是但願爲bean引入其餘別名,還能夠在name屬性中指定它們,以逗號(,)、分號(;)或空格分隔。做爲歷史記錄,在Spring 3.1以前的版本中,id屬性被定義爲xsd:ID類型,這限制了可能的字符,從3.1開始,它被定義爲xsd:string類型,注意,bean id唯一性仍然由容器執行,但再也不由XML解析器執行。函數

你不須要爲bean提供nameid,若是不顯式提供nameid,容器將爲該bean生成惟一的名稱,可是,若是你但願經過名稱引用該bean,經過使用ref元素或服務定位器樣式查找,你必須提供一個名稱,不提供名稱的動機與使用內部bean和自動裝配協做者有關。ui

Bean命名約定

約定是在爲bean命名時使用標準Java約定做爲實例字段名,也就是說,bean名稱以小寫字母開頭,並採用駝峯大小寫,此類名稱的示例包括accountManageraccountServiceuserDaologinController等等。this

一致地命名bean使你的配置更容易閱讀和理解,另外,若是你使用Spring AOP,當你將advice應用到一組按名稱關聯的bean時,它會提供很大的幫助。編碼

使用類路徑中的組件掃描,Spring按照前面描述的規則爲未命名的組件生成bean名稱:本質上,取簡單的類名並將其初始字符轉換爲小寫,可是,在(不尋常的)特殊狀況下,若是有多個字符,而且第一個和第二個字符都是大寫的,則保留原來的大小寫,這些規則與 java.beans.Introspector.decapitalize(Spring在這裏使用)定義的規則相同。

在Bean定義以外別名化Bean

在bean定義自己中,可使用id屬性指定的最多一個名稱和name屬性中任意數量的其餘名稱的組合,爲bean提供多個名稱。這些名稱能夠是相同bean的等價別名,在某些狀況下很是有用,好比經過使用特定於該組件自己的bean名稱,讓應用程序中的每一個組件引用公共依賴項。code

可是,指定實際定義bean的全部別名並不老是足夠的,有時須要爲在其餘地方定義的bean引入別名,在大型系統中,配置一般在每一個子系統之間進行劃分,每一個子系統都有本身的一組對象定義,在基於XML的配置元數據中,可使用<alias/>元素來完成此任務,下面的例子說明了如何作到這一點:

<alias name="fromName" alias="toName"/>

在這種狀況下,在使用別名定義以後,名爲fromName的bean(在同一個容器中)也能夠稱爲toName

例如,子系統A的配置元數據能夠經過subsystemA-dataSource的名稱引用數據源,子系統B的配置元數據能夠經過subsystemB-dataSource的名稱引用數據源。在組合使用這兩個子系統的主應用程序時,主應用程序經過myApp-dataSource的名稱引用數據源,要使全部三個名稱都引用同一個對象,能夠將如下別名定義添加到配置元數據中:

<alias name="myApp-dataSource" alias="subsystemA-dataSource"/>
<alias name="myApp-dataSource" alias="subsystemB-dataSource"/>

如今,每一個組件和主應用程序均可以經過唯一的名稱引用數據源,而且保證不會與任何其餘定義衝突(有效地建立名稱空間),可是它們引用的是同一個bean。

Java配置

若是使用Java配置,可使用@Bean註解提供別名,有關詳細信息,請參見使用@Bean註解。

實例化Bean

bean定義本質上是建立一個或多個對象的配方,當被詢問時,容器會查看命名bean的配方,並使用該bean定義封裝的配置元數據來建立(或獲取)一個實際對象。

若是使用基於XML的配置元數據,則要在<bean/>元素的class屬性中指定實例化的對象的類型(或類),這個class屬性(在內部是BeanDefinition實例上的一個Class屬性)一般是強制性的,你能夠經過如下兩種方式之一使用Class屬性:

  • 一般,在容器自己經過反射調用其構造函數直接建立bean的狀況下,指定要構造的bean類,這有點相似於使用new操做符的Java代碼。
  • 要指定包含建立對象時調用的static工廠方法的實際類,在不太常見的狀況下,容器調用類上的static工廠方法來建立bean,從static工廠方法調用返回的對象類型能夠是同一個類,也能夠徹底是另外一個類。
內部類的名字

若是要爲static嵌套類配置bean定義,必須使用嵌套類的二進制名稱。

例如,若是你在com.example包中有一個名爲SomeThing類,這個類有一個static嵌套類叫作OtherThing,bean定義上的class屬性的值是com.example.SomeThing$OtherThing

注意,在名稱中使用$字符將嵌套的類名與外部類名分隔開。

使用構造函數實例化

當你使用構造函數方法建立bean時,全部的普通類均可以被Spring使用並與Spring兼容,也就是說,正在開發的類不須要實現任何特定的接口或以特定的方式編碼,只需指定bean類就足夠了。可是,根據你爲特定bean使用的IoC類型,你可能須要一個默認(空)構造函數。

Spring IoC容器幾乎能夠管理你但願它管理的任何類,它不只限於管理真正的JavaBean,大多數Spring用戶更喜歡實際的JavaBean,它只有一個默認(無參數)構造函數,以及根據容器中的屬性建模的適當的settergetter。你還能夠在容器中包含更多非bean樣式的類,例如,若是你須要使用徹底不符合JavaBean規範的遺留鏈接池,Spring也能夠很好的管理它。

使用基於XML的配置元數據,你能夠指定你的bean類以下:

<bean id="exampleBean" class="examples.ExampleBean"/>

<bean name="anotherExample" class="examples.ExampleBeanTwo"/>

有關向構造函數提供參數(若是須要)和在構造對象以後設置對象實例屬性的機制的詳細信息,請參閱注入依賴項。

使用靜態工廠方法實例化

在定義使用靜態工廠方法建立的bean時,使用class屬性指定包含static工廠方法的類,使用factory-method屬性指定工廠方法自己的名稱。你應該可以調用這個方法(帶有可選參數,如後面所述)並返回一個活動對象,隨後將其視爲經過構造函數建立的,這種bean定義的一個用途是在遺留代碼中調用static工廠。

下面的bean定義指定經過調用工廠方法建立bean,定義沒有指定返回對象的類型(類),只指定包含工廠方法的類,在本例中,createInstance()方法必須是一個靜態方法,下面的例子展現瞭如何指定工廠方法:

<bean id="clientService"
    class="examples.ClientService"
    factory-method="createInstance"/>

下面的例子展現了一個使用前面bean定義的類:

public class ClientService {
    private static ClientService clientService = new ClientService();
    private ClientService() {}

    public static ClientService createInstance() {
        return clientService;
    }
}

有關向工廠方法提供(可選)參數並在對象從工廠返回後設置對象實例屬性的機制的詳細信息,請參閱依賴項和配置。

使用實例工廠方法實例化

與經過靜態工廠方法實例化相似,使用實例工廠方法實例化將從容器中調用現有bean的非靜態方法來建立新bean,要使用此機制,請保留class屬性爲空,並在factory-bean屬性中,在當前(或父或祖先)容器中指定bean的名稱,該容器包含要調用來建立對象的實例方法,使用factory-method屬性設置工廠方法自己的名稱,下面的例子展現瞭如何配置這樣一個bean:

<!-- the factory bean, which contains a method called createInstance() -->
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
    <!-- inject any dependencies required by this locator bean -->
</bean>

<!-- the bean to be created via the factory bean -->
<bean id="clientService"
    factory-bean="serviceLocator"
    factory-method="createClientServiceInstance"/>

下面的例子顯示了相應的Java類:

public class DefaultServiceLocator {

    private static ClientService clientService = new ClientServiceImpl();

    public ClientService createClientServiceInstance() {
        return clientService;
    }
}

一個工廠類也能夠包含多個工廠方法,以下例所示:

<bean id="serviceLocator" class="examples.DefaultServiceLocator">
    <!-- inject any dependencies required by this locator bean -->
</bean>

<bean id="clientService"
    factory-bean="serviceLocator"
    factory-method="createClientServiceInstance"/>

<bean id="accountService"
    factory-bean="serviceLocator"
    factory-method="createAccountServiceInstance"/>

下面的例子顯示了相應的Java類:

public class DefaultServiceLocator {

    private static ClientService clientService = new ClientServiceImpl();

    private static AccountService accountService = new AccountServiceImpl();

    public ClientService createClientServiceInstance() {
        return clientService;
    }

    public AccountService createAccountServiceInstance() {
        return accountService;
    }
}

這種方法代表,工廠bean自己能夠經過依賴項注入(DI)進行管理和配置。

在Spring文檔中,「工廠bean」指的是在Spring容器中配置的bean,它經過實例或靜態工廠方法建立對象,相反, FactoryBean(注意大小寫)指的是特定於spring的 FactoryBean

上一篇:容器概述

相關文章
相關標籤/搜索