一个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;
}
}