Spring 学习指南 第三章 bean的配置 (未完结)

第三章 bean 的配置

​ 在本章中,咱们将介绍如下内容:java

  1. bean 定义的继承:
  2. 如何解决 bean 类的构造函数的参数:
  3. 如何配置原始类型 (如 int 、float 等) 、集合类型(如 java.util.List、java.util.Map)等以及自定义类型 (如 Address ) 等的 bean 属性和构造函数参数;
  4. 如何经过使用 p 命名空间和 c 命名空间分别指定 bean 属性和构造参数来使用应用程序上下文 XML 文件变得简洁;
  5. Spring 的 FactoryBean 接口,运行编写本身的工厂类来建立 bean 实例;
  6. 模块化 bean 配置。
bean 定义的继承

​ 咱们在第一章和第二章中看到,应用程序上下文 XML 文件中的 bean 定义指定了 bean 类及其依赖项的彻底限定名称。在某些场景下,为了使 bean 定义不那么冗长,你可能但愿 bean 定义从另外一个 bean 定义继承配置信息。下面介绍 MyBank 应用中这样的一个场景。spring

MyBank——bean 定义继承实例

​ 在上一章中,咱们了解到 MyBank 应用经过 DAO 来访问数据库。假设 MyBank 应用定义了一个能够与数据库交互的 DatabaseOperations 类,所以 MyBank 应用中的全部 DAO 都依赖于 DatabaseOperations 类来执行数据库操做,以下图所示。数据库

image

​ 上图展现了 FixedDepositDao 和 PersonalBankingDao 类依赖于 DatabaseOperations 类。如下应用程序上下文 XML 文件展现了这些类的 bean 定义。apache

<bean id="databaseOperations"
    class="sample.spring.chapter01.bankapp.utils.DatabaseOperations"></bean>

<bean id="personalBankingDao" class="sample.spring.chapter01.bankapp.dao.PersonalBankingDaoImpl">
    <property name="databaseOperations" ref="databaseOperations" />
</bean>

<bean id="fixedDepositDao" class="sample.spring.chapter01.bankapp.dao.FixedDepositDaoImpl">
    <property name="databaseOperations" ref="databaseOperations" />
</bean>

​ 上面 xml 中,personalBankingDao 和 fixedDepositDao bean 定义都使用 databaseOperations 属性来引用 DatabaseOperations 实例。这意味着 PersonalBankingDaoImpl 和 FixedDepositDaoImpl 类都定义了一个 setDatabaseOperations 方法,以容许 Spring 容器注入 DatabaseOperations 实例。app

​ 若是应用程序中的 多个 bean 共享一组公共的配置 (属性、构造函数参数等),则能够建立一个 bean 定义,做为其余 bean 定义的父定义。在 personalBankingDao 和 fixedDepositDao bean定义中,公共的配置是 databaseOperations 属性。下面展现了 personalBankingDao 和 fixedDepositDao bean 定义如何从父 bean 定义继承 databaseOperations 属性。dom

<bean id="databaseOperations" class="sample.spring.chapter03.bankapp.utils.DatabaseOperations"></bean>

<bean id="daoTemplate" abstract="true">
    <property name="databaseOperations" ref="databaseOperations" />
</bean>

<bean id="fixedDepositDao" parent="daoTemplate" class="sample.spring.chapter03.bankapp.dao.FixedDepositDaoImpl">
</bean>

<bean id="personalBankingDao" parent="daoTemplate" 
      class="sample.spring.chapter03.bankapp.dao.PersonalBankingDaoImpl"></bean>

​ 在上面的 xml 中,daoTemplate bean 定义了 fixedDepositDao 和 personalBankingDao bean 定义共享的公共配置。因为 fixedDepositDao 和 personalBankingDao bean 定义都须要 databaseOperations 依赖项,daoTemplate bean 定义使用 元素定义 databaseOperations 依赖项。 元素的 parent 属性指定从中继承配置的 bean 定义的名称。因为 fixedDepositDao 和 personalBankingDao bean 定义中的 parent 属性值为 daoTemplate ,所以他们从 daoTemplate bean 定义继承了 databaseOperation 属性。 模块化

​ 若是 元素的 abstract 特性值设置为 true , 则表示 bean 定义是抽象的。在上面 xml 中, daoTemplate bean 定义是抽象的。请注意,Spring 容器不会尝试建立一个与抽象 bean 定义相对应的 bean 。 函数

注意:
    抽象 bean 不能做为其余 bean 定义的依赖项,也就是说,不能使用 <property> 或 <constructor-arg> 元素来引用抽象  bean 。

​ 你可能已经注意到 daoTemplate bean 定义没有指定 class特性。若是父 bean 定义没有指定 class特性,则须要在子 bean 定义 (如 fixedDepositDao 和 personalBankingDao) 中指定 class 特性。注意,若是不指定 class 特性,则必须将 bean 定义为抽象的,以使 Spring 容器不会去尝试建立与之对应的 bean实例。spa

​ 要验证 fixedDepositDao 和 personalBankingDao bean 定义是否继承了 daoTemplate bean 定义的 databaseOperations 属性。请执行下面的 java 代码。BankApp 类的 main 方法调用在 fixedDepositDao 和 personalBankingDao bean 中的方法,而这些 bean 调用 DatabaseOperations 实例上的方法。你会注意到,BankApp 的 main 方法成功运行。没有抛出任何异常。若是没有将 DatabaseOperations 实例注入 fixedDepositDao 和 personalBankingDao bean 中,那么代码将抛出 java.lang.NullPointerException。3d

package sample.spring.chapter03.bankapp;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import sample.spring.chapter03.bankapp.controller.FixedDepositController;
import sample.spring.chapter03.bankapp.controller.PersonalBankingController;
import sample.spring.chapter03.bankapp.domain.FixedDepositDetails;

public class BankApp {
    private static Logger logger = Logger.getLogger(BankApp.class);

    public static void main(String args[]) {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "classpath:META-INF/spring/applicationContext.xml");

        FixedDepositController fixedDepositController = context
                .getBean(FixedDepositController.class);
        fixedDepositController.submit(context
                .getBean(FixedDepositDetails.class).setDepositAmount(100)
                .setEmail("someemail@somedomain.com").setId(1).setTenure(10));
        logger.info("Your fixed deposit details : " + fixedDepositController.get());

        PersonalBankingController personalBankingController = context
                .getBean(PersonalBankingController.class);
        logger.info(personalBankingController.getMiniStatement());
        
    }
}

​ 下图 显示了 fixedDepositDao 和 personalBankingDao bean 定义中,bean 定义继承是如何工做的

image

​ 上图展现了 fixedDepositDao 和 personalBankingDao bean 定义从 daoTemplate bean 定义继承了 databaseOperations 属性(以 fixedDeopsitDa 和 personalBankingDao 标识的方框中的 property 属性)。上图还描述了 Spring 容器不会尝试建立 与 daoTemplate bean 定义相对应的bean 实例,由于他被标记为 abstract。

继承了什么

​ 子 bean 定义从 父 bean 定义继承一下配置信息:

  1. 属性,经过 元素指定。
  2. 构造函数参数,经过 元素指定。
  3. 方法覆盖(见4,5节)
  4. 初始化和销毁方法(见 第五章);
  5. 工厂方法,经过 元素的 工厂方法特性指定(见2,3节,了解静态和实例工厂方法如何用于建立 bean)
相关文章
相关标签/搜索