天天看点

(1.0)Spring的IoC容器之BeanFactory

第4章 Spring的IoC容器之BeanFactory

本章内容

拥有BeanFactory之后的生活

BeanFactory的对象注册与依赖绑定方式

BeanFactory的XML之旅

容器背后的秘密

我们前面说过,Spring的IoC容器是一个IoC Service Provider,但是,这只是它被冠以IoC之名的部分原因,我们不能忽略的是"容器"。Spring的IoC容器是一个提供IoC支持的轻量级容器,除了基本的IoC支持,它作为轻量级容器还提供了IoC之外的支持。如在Spring的IoC容器之上,Spring还提供了相应的AOP框架支持、企业级服务集成等服务。Spring的IoC容器和IoC Service Provider所提供的服务之间存在一定的交集,二者的关系如图4-1所示。

(1.0)Spring的IoC容器之BeanFactory
图4-1 Spring的IoC容器和IoC Service Provider之间的关系

注意 本章将主要关注Spring的IoC容器提供的IoC相关支持以及衍生的部分高级特性。而IoC容器提供的其他服务将在后继章节中陆续阐述。

Spring提供了两种容器类型:BeanFactory和ApplicationContext。

BeanFactory。基础类型IoC容器,提供完整的IoC服务支持。如果没有特殊指定,默认采用延迟初始化策略(lazy-load)。只有当客户端对象需要访问容器中的某个受管对象的时候,才对该受管对象进行初始化以及依赖注入操作。所以,相对来说,容器启动初期速度较快,所需要的资源有限。对于资源有限,并且功能要求不是很严格的场景,BeanFactory是比较合适的IoC容器选择。

ApplicationContext。ApplicationContext在BeanFactory的基础上构建,是相对比较高级的容器实现,除了拥有BeanFactory的所有支持,ApplicationContext还提供了其他高级特性,比如事件发布、国际化信息支持等,这些会在后面详述。ApplicationContext所管理的对象,在该类型容器启动之后,默认全部初始化并绑定完成。所以,相对于BeanFactory来说,ApplicationContext要求更多的系统资源,同时,因为在启动时就完成所有初始化,容器启动时间较之BeanFactory也会长一些。在那些系统资源充足,并且要求更多功能的场景中,ApplicationContext类型的容器是比较合适的选择。

通过图4-2,我们可以对BeanFactory和ApplicationContext之间的关系有一个更清晰的认识。

(1.0)Spring的IoC容器之BeanFactory
(点击查看大图)图4-2 BeanFactory和ApplicationContext继承关系

注意 ApplicationContext间接继承自BeanFactory,所以说它是构建于BeanFactory之上的IoC容器。此外,你应该注意到了,ApplicationContext还继承了其他三个接口,它们之间的关系,我们将在第5章中详细说明。

另外,在没有特殊指明的情况下,以BeanFactory为中心所讲述的内容同样适用于Applica- tionContext,这一点需要明确一下,二者有差别的地方会在合适的位置给出解释。

BeanFactory,顾名思义,就是生产Bean的工厂。当然,严格来说,这个"生产过程"可能不像说起来那么简单。既然Spring框架提倡使用POJO,那么把每个业务对象看作一个JavaBean对象,或许更容易理解为什么Spring的IoC基本容器会起这么一个名字。作为Spring提供的基本的IoC容器,BeanFactory可以完成作为IoC Service Provider的所有职责,包括业务对象的注册和对象间依赖关系的绑定。

BeanFactory就像一个汽车生产厂。你从其他汽车零件厂商或者自己的零件生产部门取得汽车零件送入这个汽车生产厂,最后,只需要从生产线的终点取得成品汽车就可以了。相似地,将应用所需的所有业务对象交给BeanFactory之后,剩下要做的,就是直接从BeanFactory取得最终组装完成并且可用的对象。至于这个最终业务对象如何组装,你不需要关心,BeanFactory会帮你搞定。

所以,对于客户端来说,与BeanFactory打交道其实很简单。最基本地,BeanFactory肯定会公开一个取得组装完成的对象的方法接口,就像代码清单4-1中真正的BeanFactory的定义所展示的那样。

代码清单4-1 BeanFactory的定义

  1. public interface BeanFactory {  
  2.     String FACTORY_BEAN_PREFIX = "&";  
  3.     Object getBean(String name) throws BeansException;  
  4.     Object getBean(String name, Class requiredType)  throws BeansException;  
  5.     /**  
  6.      * @since 2.5  
  7.      */ 
  8.     Object getBean(String name, Object[] args)  throws BeansException;  
  9.     boolean containsBean(String name);  
  10.     boolean isSingleton(String name) throws  NoSuchBeanDefinitionException;  
  11.     /**  
  12.      * @since 2.0.3  
  13.      */ 
  14.     boolean isPrototype(String name) throws  NoSuchBeanDefinitionException;  
  15.     /**  
  16.      * @since 2.0.1  
  17.      */ 
  18.     boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException;  
  19.     Class getType(String name) throws NoSuchBeanDefinitionException;  
  20.     String[] getAliases(String name);  

上面代码中的方法基本上都是查询相关的方法,例如,取得某个对象的方法(getBean)、查询某个对象是否存在于容器中的方法(containsBean),或者取得某个bean的状态或者类型的方法等。因为通常情况下,对于独立的应用程序,只有主入口类才会跟容器的API直接耦合。

继续阅读