Spring IoC容器实现了IoC设计模式。本章并不关注Spring IoC容器的具体实现细节,而是重点关注如何访问和使用Spring IoC容器。
为实现对Spring IoC容器的访问,应用代码可以通过如下两个接口完成。
BeanFactory:位于org.springframework.beans.factory包中。开发者借助于配置文件(比如,XML或属性文件),能够实现对JavaBean的配置和管理。主要用于开发Java应用,尤其是在物理资源(内存有限)受限的场合,比如Applet应用。
ApplicationContext:位于org.springframework.context包中。ApplicationContext构建在BeanFactory基础之上,即继承于它。除了具有BeanFactory的功能之外,它还添加了其他大量功能,比如同Spring IoC集成、(为实现国际化而)处理消息资源、(为应用对象发布和注册通知事件而)添加了事件、声明(非)容器提供的服务等。主要用于开发J2EE应用,这也是Spring推荐使用的接口。
BeanFactory:
Spring BeanFactory是非常轻量的,它处于Spring框架的核心。开发者可以将它用于Applet应用和单独的Swing/SWT应用中,因此开发者需要对BeanFactory有足够的了解。当然,对于EJB应用而言也同样合适。在整个Spring框架中都存在BeanFactory的概念,即统一使用BeanFactory访问Spring IoC容器。开发者通过使用BeanFactory能够定义和提供良好的业务对象层,从技术架构的角度考虑,这是很合理的。
当应用创建BeanFactory实例时,实际上是完成了JavaBean的实例化、配置以及管理,即BeanFactory在访问和操作IoC容器的初期充当了IoC容器的作用。其中,BeanFactory具体使用的Spring配置文件定义了各个JavaBean之间的关系。
对于应用需要直接实例化BeanFactory实例的场合而言,XmlBeanFactory使用尤为广泛。让我们再次回到example4吧。为便于阅读本书,在此再一次给出appcontext.xml和HelloWorldClient客户应用。
首先,看看appcontext.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean name="fileHelloWorld"
class="com.openv.spring.HelloWorld">
<constructor-arg>
<ref bean="fileHello"/>
</constructor-arg>
</bean>
<bean name="fileHello"
class="com.openv.spring.FileHelloStr">
<constructor-arg>
<value>helloworld.properties</value>
</constructor-arg>
</bean>
</beans>
开发者是否注意到其中的粗斜体内容。Spring配置文件(appcontext.xml)必须遵循spring-beans.dtd定义的内容模型。其中,spring-beans.dtd为JavaBean命名空间提供了一种简单、一致的定义方式,供BeanFactory配置使用。大部分Spring框架提供的功能都需要使用到它,包括基于BeanFactory的Web应用上下文。本书附录B详细给出了spring-beans.dtd的内容模型。
其一,基于文件找到appcontext.xml。示例代码如下:
try {
InputStream ins = new FileInputStream("src/appcontext.xml");
BeanFactory factory = new XmlBeanFactory(ins);
HelloWorld hw = (HelloWorld) factory.getBean("fileHelloWorld");
log.info(hw.getContent());
} catch (FileNotFoundException ex) {
log.error("文件appcontext.xml未找到", ex);
}
其二,基于ApplicationContext实现类找到appcontext.xml文件。示例代码如下:
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] { "appcontext.xml" });
BeanFactory factory = (BeanFactory) appContext;
HelloWorld hw = (HelloWorld) factory.getBean("fileHelloWorld");
log.info(hw.getContent());
Bean的生命周期
本节将重点研究一下BeanFactory中Bean的生命周期。借助于IoC容器,即通过BeanFactory能够实现对JavaBean的控制反转。IoC容器定义了Spring配置文件中JavaBean应遵循的规则。Spring将其称之为BeanDefinition,即Bean定义。大体上看,任何处于IoC容器控制下的JavaBean的生命周期都存在4个阶段。
实例化JavaBean。
JavaBean实例的初始化,即通过IoC注入其依赖性。这一阶段将完成JavaBean实例的初始化。
基于Spring应用对JavaBean实例的使用。
IoC容器销毁JavaBean实例。