1、第 19章 Spring的 IoC 本章将详细深入地探讨 Spring框架的控制反转实现( Inversion of Control, IoC)原理。 Spring框架所提供的众多功能之所以能成为一个整体,正是创建在 IoC的基础之上,因此对这一内涵简单、外延丰富的技术有必要进行详细的介绍。19.1 Bean工厂 org.springframework.beans.factory.BeanFactory是 Spring IoC容器的实际代表者, IoC容器负责容纳此前所描述的 bean,并对bean进行管理。如图所示, Spring中 IoC容器就是对象的加工厂,可以按照元数据填充和组装 Ja
2、va对象。19.1.1 创建 Bean工厂 在 Spring中, BeanFactory是 IoC容器的核心接口。它的职责包括:实例化、定位、配置应用程序中的对象及创建这些对象间的依赖。 从本质上讲, BeanFactory仅仅只是一个维护 bean定义以及相互依赖关系的高级工厂接口。通过BeanFactory可以访问 bean定义。 Spring提供了许多易用的 BeanFactory实现, XmlBeanFactory就是最常用的一个。该实现将以 XML方式描述组成应用的对象以及对象间的依赖关系。 XmlBeanFactory类将持有此 XML配置元数据,并用它来构建一个完全可配置的系统或
3、应用。19.1.2 使用多个文件 将 XML配置文件分拆成多个部分是非常有用的。为了加载多个 XML文件生成一个 ApplicationContext实例,可以将文件路径作为字符串数组传给ApplicationContext构造函数。而 bean factory将通过调用 bean defintion reader从多个文件中读取 bean定义。 通常情况下, Spring团队倾向于上述做法,因为这样各个配置并不会查觉到它们与其他配置文件的组合。另外一种方法是使用一个或多个的元素来从另外一个或多个文件加载 bean定义。19.1.3 获取 Bean 就 Spring IoC容器而言, bean
4、定义基本上描述了创建一个或多个实际 bean对象的内容。当需要的时候,容器会从 bean定义列表中取得一个指定的bean定义,并根据 bean定义里面的配置元数据使用反射机制来创建一个实际的对象。 当使用基于 XML的元数据配置文件,可以这样来指定 bean类: 19.1.4 BeanFactory的其它方法 除了 getBean()方法可以取得 bean的实例;BeanFactory还提供其他的方法供客户代码调用: boolean containsBean(String):如果BeanFactory包含给定名称的 bean定义 (或 bean实例 ),则返回 true。 Object get
5、Bean(String):返回以给定名字注册的 bean实例。根据 bean的配置情况,如果为singleton模式将返回一个共享的实例,否则将返回一个新建的实例。如果没有找到指定的 bean,该方法可能会抛出 BeansException异常 (实际上将抛出 NoSuchBeanDefinitionException异常 ),在对 bean进行实例化和预处理时也可能抛出异常19.1.4 BeanFactory的其它方法 Object getBean(String, Class):返回以给定名称注册的 bean实例,并转换为给定 class类型的实例,如果转换失败,相应的异常 (BeanNot
6、OfRequiredTypeException)将被抛出。上面的 getBean(String)方法也适用该规则。 Class getType(String name):返回给定名称的 bean的Class。如果没有找到指定的 bean实例,则抛出NoSuchBeanDefinitionException异常。 boolean isSingleton(String):判断给定名称的 bean定义(或 bean实例 )是否为 singleton模式 (singleton将在 bean的作用域中讨论 ),如果 bean没找到,则抛出NoSuchBeanDefinitionException异常。
7、String getAliases(String):返回给定 bean名称的所有别名。19.2 配置 Bean 在 Spring中,那些组成应用的主体( backbone)及由 Spring IoC容器所管理的对象被称之为 bean。简单地讲, bean就是由 Spring容器初始化、装配及被管理的对象,除此之外, bean就没有特别之处了(与应用中的其他对象没有什么区别)。而 bean定义以及 bean相互间的依赖关系将通过配置元数据来描述。19.2.1 bean的定义 Spring IoC容器将管理一个或多个 bean,这些 bean将通过配置文件中的 bean定义被创建 (在 XML格式
8、中为 元素)。在容器内部,这些 bean定义由 BeanDefinition 对象来表示,该定义将包含以下信息: 全限定类名:这通常就是已定义 bean的实际实现类。如果通过调用 static factory方法来实例化 bean,而不是使用常规的构造函数,那么类名称实际上就是工厂类的类名。 bean行为的定义,即创建模式( prototype还是 singleton)、自动装配模式、依赖检查模式、初始化以及销毁方法。这些定义将决定 bean在容器中的行为用于创建 bean实例的构造函数参数及属性值。比如使用 bean来定义连接池,可以通过属性或者构造参数指定连接数,以及连接池大小限制等。 b
9、ean之间的关系,即协作 (或者称依赖 )。19.2.2 bean命名约定 bean的命名采用标准的 Java命名约定,即小写字母开头,首字母大写间隔的命名方式。如accountManager、 accountService、 userDao及loginController,等等。 对 bean采用统一的命名约定将会使配置更加简单易懂。而且在使用 Spring AOP时,如果要发通知(advice)给与一组名称相关的 bean时,这种简单的命名方式将会带来额外的好处,如可以使用统配符来一次配置多个 bean。 每个 bean都有一个或多个 id(或称之为标识符或名称,在术语上可以理解成一回事)。这些 id在当前 IoC容器中必须唯一。如果一个 bean有多个 id,那么其他的 id在本质上将被认为是别名。