Spring 学习指南 第三章 bean的配置 (未完结),
Spring 学习指南 第三章 bean的配置 (未完结),
第三章 bean 的配置
在本章中,我们将介绍以下内容:
bean 定义的继承
我们在第一章和第二章中看到,应用程序上下文 XML 文件中的 bean 定义指定了 bean 类及其依赖项的完全限定名称。在某些场景下,为了使 bean 定义不那么冗长,你可能希望 bean 定义从另一个 bean 定义继承配置信息。下面介绍 MyBank 应用中这样的一个场景。
MyBank——bean 定义继承实例
在上一章中,我们了解到 MyBank 应用通过 DAO 来访问数据库。假设 MyBank 应用定义了一个可以与数据库交互的 DatabaseOperations 类,因此 MyBank 应用中的所有 DAO 都依赖于 DatabaseOperations 类来执行数据库操作,如下图所示。
上图展示了 FixedDepositDao 和 PersonalBankingDao 类依赖于 DatabaseOperations 类。以下应用程序上下文 XML 文件展示了这些类的 bean 定义。
<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 实例。
如果应用程序中的 多个 bean 共享一组公共的配置 (属性、构造函数参数等),则可以创建一个 bean 定义,作为其他 bean 定义的父定义。在 personalBankingDao 和 fixedDepositDao bean定义中,公共的配置是 databaseOperations 属性。下面展示了 personalBankingDao 和 fixedDepositDao bean 定义如何从父 bean 定义继承 databaseOperations 属性。
<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 定义使用
如果
注意:
抽象 bean 不能作为其他 bean 定义的依赖项,也就是说,不能使用 <property> 或 <constructor-arg> 元素来引用抽象 bean 。
你可能已经注意到 daoTemplate bean 定义没有指定 class特性。如果父 bean 定义没有指定 class特性,则需要在子 bean 定义 (如 fixedDepositDao 和 personalBankingDao) 中指定 class 特性。注意,如果不指定 class 特性,则必须将 bean 定义为抽象的,以使 Spring 容器不会去尝试创建与之对应的 bean实例。
要验证 fixedDepositDao 和 personalBankingDao bean 定义是否继承了 daoTemplate bean 定义的 databaseOperations 属性。请执行下面的 java 代码。BankApp 类的 main 方法调用在 fixedDepositDao 和 personalBankingDao bean 中的方法,而这些 bean 调用 DatabaseOperations 实例上的方法。你会注意到,BankApp 的 main 方法成功运行。没有抛出任何异常。如果没有将 DatabaseOperations 实例注入 fixedDepositDao 和 personalBankingDao bean 中,那么代码将抛出 java.lang.NullPointerException。
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 定义继承是如何工作的
上图展示了 fixedDepositDao 和 personalBankingDao bean 定义从 daoTemplate bean 定义继承了 databaseOperations 属性(以 fixedDeopsitDa 和 personalBankingDao 标识的方框中的 property 属性)。上图还描述了 Spring 容器不会尝试创建 与 daoTemplate bean 定义相对应的bean 实例,因为他被标记为 abstract。
继承了什么
子 bean 定义从 父 bean 定义继承一下配置信息:
相关文章
- 暂无相关文章
用户点评