5.3.1 Spring核心接口
Spring有两个核心接口BeanFactory和ApplicationContext,ApplicationContext是BeanFactory的子接口。它们代表了Spring容器。
1.BeanFactory
在Spring中有几种BeanFactory的实现,其中最常使用的是org.springframework.bean.factory.xml.XmlBeanFactory。它根据XML文件中的定义装载Bean。
要创建XmlBeanFactory,需要传递一个java.io.InputStream对象给构造函数。InputStream对象提供XML文件给工厂。例如,下面的代码片段使用一个java.io.FileInputStream对象把Bean XML定义文件给XmlBeanFactory:
BeanFactory factory = new XmlBeanFactory(new FileInputStream(" applicationContext.xml"));
这行简单的代码告诉Bean Factory从XML文件中读取Bean的定义信息,但是现在Bean Factory没有实例化Bean,Bean被延迟载入到Bean Factory中,就是说Bean Factory会立即把Bean定义信息载入进来,但是Bean只有在需要的时候才被实例化。
为了从BeanFactory得到Bean,只要简单地调用getBean()方法,把需要的Bean的名字当做参数传递进去就行了。由于得到的是Object类型,所以要进行强制类型转化。
MyBean myBean = (MyBean)factory.getBean(“myBean”);
2. ApplicationContext
两者都是载入Bean定义信息,装配Bean,根据需要分发Bean。但是ApplicationContext提供了更多功能:
① 应用上下文提供了文本信息解析工具,包括对国际化的支持。
② 应用上下文提供了载入文本资源的通用方法,如载入图片。
③ 应用上下文可以向注册为监听器的Bean发送事件。
由于它提供的附加功能,几乎所有的应用系统都选择ApplicationContext,而不是BeanFactory。
在ApplicationContext的诸多实现中,有三个常用的实现:
ClassPathXmlApplicationContext:从类路径中的XML文件载入上下文定义信息,把上下文定义文件当成类路径资源。
FileSystemXmlApplicationContext:从文件系统中的XML文件载入上下文定义信息。
XmlWebApplicationContext:从Web系统中的XML文件载入上下文定义信息。
例如:
ApplicationContext context=new FileSystemXmlApplicationContext ("c:/foo.xml");
ApplicationContext context=new ClassPathApplicationContext ("foo.xml");
ApplicationContext context=WebApplicationContextUtils.getWebApplicationContext (request.getSession().getServletContext ());
FileSystemXmlApplicationContext和ClassPathXmlApplicationContext的区别是:FileSystemXmlApplicationContext只能在指定的路径中寻找foo.xml文件,而ClassPathXml ApplicationContext可以在整个类路径中寻找foo.xml。
BeanFactory是在getBean()方法调用时创建Bean。ApplicationContext会在上下文启动后预载入所有的单实例Bean,以确保需要的时候已经准备好了。
5.3.2 Spring基本配置
在Spring内拼接Bean叫做装配。
1.使用XML装配
理论上,Bean装配可以从任何配置资源获得。但实际上,XML是最常见的Spring应用系统配置源。
如下的XML文件展示了一个简单的Spring上下文定义文件:
<?xml version="1.0" encoding="UTF-8"?>
…
<beans …> // 根元素
<bean id="foo" class="com.spring.Foo"/> // Bean实例
<bean id="bar" class="com.spring.Bar"/> // Bean实例
</beans>
在XML文件定义Bean,上下文定义文件的根元素<beans>。<beans>有多个<bean>子元素。每个<bean>元素定义了一个Bean(任何一个Java对象)如何被装配到Spring容器中。
2.添加一个Bean
向Spring容器中添加一个Bean只需要向XML文件中添加一个<bean>元素。如下面的语句:
<bean id="foo" class="com.spring.Foo"/>
当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。
① 原型模式与单实例模式:Spring中的Bean默认情况下是单实例模式。在容器分配Bean的时候,它总是返回同一个实例。
<bean>的singleton属性告诉ApplicationContext这个Bean是不是单实例Bean,默认是true,但是把它设置为false的话,就把这个Bean定义成了原型Bean。
<bean id="foo" class="com.spring.Foo" singleton="false"/> //原型模式Bean
② request或session:对于每次HTTP请求或HttpSession,使用request或session定义的Bean都将产生一个新实例,即每次HTTP请求或HttpSession将会产生不同的Bean实例。
③ global session:每个全局的HttpSession对应一个Bean实例。典型情况下,仅在使用portlet context的时候有效。
当一个Bean实例化的时候,有时需要做一些初始化的工作,然后才能使用。因此,Spring可以在创建和拆卸Bean的时候调用Bean的两个生命周期方法。
在Bean的定义中设置自己的init-method,这个方法在Bean被实例化时马上被调用。同样,也可以设置自己的destroy-method,这个方法在Bean从容器中删除之前调用。
一个典型的例子是连接池Bean。
public class MyConnectionPool{
…
public void initalize(){//initialize connection pool}
public void close(){ //release connection}
…
}
Bean的定义如下:
<bean id="connectionPool" class="com.spring.MyConnectionPool"
init-method="initialize" //当Bean被载入容器时调用initialize方法
destroy-method="close"> //当Bean从容器中删除时调用close方法
</bean>