Spring IoC 容器 和 Beans
IoC也称作dependency injection(DI).
org.springframework.beans和org.springframework.context库时IoC容器的基础。
BeanFactory接口提供了管理任意类型对象的机制。ApplicationContext是BeanFactory的子接口,它添加了AOP,message resource handling,event publication等特征。
BeanFactor提供了基本的功能和配置框架,而ApplicationContext添加了更多的企业化的功能。ApplicationContext时BeanFactory的超集。
Spring中,IoC容器管理的对象称为benas;
Spring容器
接口org.springframework.context.ApplicationContext代表Spring IoC容器,负责实例化,配置,装配beans。Spring容器通过读取配置元数据来获得实例化,配置,装配的对象的说明。配置元数据(Configuration Metadata)可以时XML文件,Java注解Annotation,或者Java Doc。
Spring提供了一些ApplicationContext接口的直接实现;例如在一个standalone应用中,通常创建一个ClassPathXmlApplicationContext或FileSystemXmlApplicationContext实例。XML是定义配置元数据的传统形式,在其中可以指定容器使用java 注解或 java code作为实际的元数据配置的形式。
在大部分的应用中,并不需要显式的实例化Spring IoC容器的实例(ApplicationContext),例如在web应用中,通过在web.xml中进行配置。
Configuration Metadata
传统上,使用基于XML格式的文件作为配置文件。
也可以使用基于注解的配置和基于java的配置。
基于XML格式的配置文件基本格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
</beans>
实例化容器
示例:
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
bean的定义可以放在多个XML文件中。
可以使用上面的构造函数将这些文件传入;或者,使用<import>元素从其他文件加载bena定义,例如:
<beans>
<import resource="services.xml"/>
<import resource="resources/messageSource.xml"/>
<import resource="/resources/themeSource.xml"/>
<bean id="bean1" class="..."/>
<bean id="bean2" class="..."/>
</beans>
(不推荐使用父路径,即在路径最前面使用“/”)。
使用容器
使用ApplicationContext对象的方法 :
T getBean(String name, Class<T> requriedType);
获得bean的实例。
例如:
// create and configure beans
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);
// use configured instance
List<String> userList = service.getUsernameList();
Spring Bean
在Spring容器中,使用BeanDefinition对象来表示bean定义,BeanDefiniton对象包含下列信息:
- a package-qualified class name —— 该bean所定义的实际的类名
- bean behavior configuration elements —— 例如scope, lifecycle, callback等
- collaborator dependencies —— 该bean中所引用的其他的bean
- 其他配置 —— 如连接池的大小等
Bean definition的属性
- class
- name
- scope
- constructor arguments
- properties
- autowiring mode
- lazy-initialization mode
- initialization method
- destruction method
Bean的命名
一个Bean通常只有一个标识符;如果需要多个的话,可以将其他的标识符看作是别名(aliases).
在基于XML格式的配置中,使用 id 或 name 属性指定bean的标识。
在bean定义的外部,可以指定bean的别名;例如,在基于XML的配置中:
<alias name="fromName" alias="toName" />
他们实际都指向同一个bena对象。
实例化Bean
如果使用基于XML的配置,需要在<bean>元素的 class 属性中指定需要实例化对象的类型。class 属性映射到 BeanDefiniton对象的Class属性。
使用构造函数实例化
大部分的spring用户倾向于使用仅有默认构造函数的JavaBean,并提供setter和getter方法。
使用静态厂方法实例化
例如:
<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 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;
}
}