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)
相關文章
相關標籤/搜索