一個Spring IoC容器管理着一個或多個Bean,這些Bean是由配置的元數據來創建的。一個Bean定義包含的元素有:一個全路徑類名、Bean行爲配置元素、對其它Bean的引用和配置信息。除了可以通過定義的信息來創建Bean以外,ApplicationContext的實現類也允許將容器外已有的類註冊爲Bean,一般情況下用不到。
1 Bean的命名
一個Bean通常有一個或多個標識,在一個容器中,這種標識必須是唯一的。通常情況下,一個Bean僅有一個標識,若還有多個,那麼其它的就作爲別名來使用。在基於XML文件的配置元數據中,我們使用id或者name來指定一個Bean的標識。id屬性只能用來指定一個名字,如果要爲Bean指定別名,那麼可以通過name來指定,使用逗號、分號或空格來分隔。
如果沒有特殊需求,我們不需要爲一個Bean提供一個id或者name,容器可以爲Bean自動生成一個唯一的名字。如果你想通過名字來引用一個Bean,你必須爲這個Bean提供一個名字,那樣就可以通過ref元素來查找。
在Java中,我們習慣使用駝峯法來命名一個Bean,比如accountService。對Bean的命名需要保持一致性,這樣就使得配置更易於閱讀和理解。
爲Bean單獨取別名
在Bean定義中,我們可以通過name來爲Bean取多個別名。然而,把所有的別名全都放在Bean定義中並不一定合適,有時我們需要在Bean定義之外爲之取一個別名。特別是在大型系統中,每個子系統都有自己獨立的配置文件,那麼我們可以通過使用<alias></alias>標籤來爲一個Bean指定別名。
- <alias name="fromName" alias="toName"/>
在這種情況下,一個叫做fromName的Bean被取了一個別名toName。
2 實例化Bean
實際上,一個Bean定義就是一個創建對象的菜譜,當需要使用到這個Bean的實例時,容器就通過name找到這個Bean,並根據配置元數據來創建一個實際的對象。在基於XML的配置元數據中,我們可以通過class屬性來指定一個Bean的類型,這個class屬性通常是強制需要指定的。有以下幾種實例化方法:
使用構造器進行實例化
當我們通過構造器方式創建了一個Bean,這樣的Bean都是Spring可以使用和兼容的。因此,這個類不需要實現特定的接口,也不需要以特定的風格進行編碼。僅僅指定Bean的class就足夠了。然而,根據你使用何種類型的IoC,你也許會需要一個默認(空的)構造器。
使用基於XML的配置元數據,可以像如下這樣指定Bean:
- <bean id="exampleBean" class="examples.ExampleBean"/>
- <bean name="anotherExample" class="examples.ExampleBeanTwo"/>
使用靜態工廠方法進行實例化
當你使用靜態工廠方法來創建一個Bean時,class用來指定類名,factory-method用來指定這個類中的靜態方法。你應該可以調用這個方法並且返回一個對象,就如通過一個構造器創建的Bean。下面的Bean對象通過調用一個工廠方法來創建:
- <bean id="clientService"
- class="examples.ClientService"
- factory-method="createInstance"/>
- public class ClientService {
- private static ClientService clientService = new ClientService();
- private ClientService() {}
- public static ClientService createInstance() {
- return clientService;
- }
- }
使用實例工廠方法進行實例化
跟使用靜態工廠方法進行實例化類似,使用實例工廠方法進行實例化調用一個非靜態的方法來創建一個新的Bean。爲了使用這種機制,將class屬性置爲空,指定一個Bean(包含創建對象的方法)的name,然後在factory-method屬性中指定工廠方法。
- <!-- 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"/>
- public class DefaultServiceLocator {
- private static ClientService clientService = new ClientServiceImpl();
- private DefaultServiceLocator() {}
- 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"/>
- public class DefaultServiceLocator {
- private static ClientService clientService = new ClientServiceImpl();
- private static AccountService accountService = new AccountServiceImpl();
- private DefaultServiceLocator() {}
- public ClientService createClientServiceInstance() {
- return clientService;
- }
- public AccountService createAccountServiceInstance() {
- return accountService;
- }
- }