Spring IoC容器管理这多个beans,这些beans通过我们传入给容器的配置元数据(configuration metadata)来创建这些beans。
Beans
在容器内部,这些bean定义使用对象 BeanDefiniton 来表示,该对象包含下列内容:
- bean的实际类类型
- bean的行为,如scope, lifecycle callbackz等
- 该bean所引用的其他的依赖的bean
- 其他配置,如连接池的数量,大小等
除了包含如何创建bean的信息外,ApplicationContext的实现类也可以用来注册在Spring 容器外部创建的对象。当然,我们通常仅仅使用通过配置元数据指定的beans。
命名Beans
每一个bean都拥有一个或多个标识符;这些标识符在Spring 容器中必须是唯一的。通常,bean只有一个标识符,如果需要多个标识符,则其他标识符被当作是bean的别名。
在基于XML文件的配置元数据中,使用 id 或者 name作为bean的标识符。通常使用 id 作为唯一标识符,而使用name来作为别名。
id 和 name 属性对于bean来说并不是强制需要的;如果没有显式地指定一个 name 或 id,则容器会自动生成一个唯一的标识符。
如果想要通过 ref 元素来引用其他的bean,那么个必须提供一个bean的标识符;不使用显式标识符的情况通常是在使用 inner beans 或者 autowring collaborators。
在Bean的定义外定义别名
例如:
<alias name="fromName" alias="toName"/>
该bean的名称为 fromName,在使用别名定义后,可以使用名称 toName 来引用它。
实例化Beans
如果使用基于XML文件的配置元数据,<bean/>元素中的class属性表示实例化对象的类型,该属性是强制的。
class属性具有两种使用形式:
- 通常,指定为需要构造的bean的类型,容器通过调用其构造函数来创建这个bean,相当于使用new 操作符来创建bean
- 指定一个包含静态厂方法的类,通过调用该静态的厂方法来创建这个bean
内部类-需要使用二进制的内部类名,如com.example.Foo$Bar
使用构造函数来实例化Bean
如果通过构造函数来实例化bean,那么该类不需要实现特定的接口或者是遵循某种特定的规范。但是,有时候根据使用何种方式的IoC,可能需要包含一个默认的构造函数。
通常情况下,我们更偏向于使用JavaBeans形式的类,即包含一个默认的构造函数,同时包含一系列的setter和getter方法来获取/设置类的属性。
使用静态厂方法来实例化Bean
使用静态厂方法,需要在class属性中指定一个包含静态厂方法的类,同时包含一个属性 factory-method 来指定这个厂方法。该方法返回一个对象。
例如:
<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
该方法通过调用一个已存在的bean的非静态方法来创建一个新的bean。这种情况下, class属性为空, 在factory-bean属性中指定一个当前容器中的bean的名称,使用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;
}
}