Spring 学习指南 第三章 bean的配置 (未完结)
第三章 bean 的配置
在本章中,我们将介绍以下内容:
- bean 定义的继承:
- 如何解决 bean 类的构造函数的参数:
- 如何配置原始类型 (如 int 、float 等) 、集合类型(如 java.util.list、java.util.map)等以及自定义类型 (如 address ) 等的 bean 属性和构造函数参数;
- 如何通过使用 p 命名空间和 c 命名空间分别指定 bean 属性和构造参数来使用应用程序上下文 xml 文件变得简洁;
- spring 的 factorybean 接口,运行编写自己的工厂类来创建 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 定义使用
如果
你可能已经注意到 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。 下图 显示了 fixeddepositdao 和 personalbankingdao bean 定义中,bean 定义继承是如何工作的 上图展示了 fixeddepositdao 和 personalbankingdao bean 定义从 daotemplate bean 定义继承了 databaseoperations 属性(以 fixeddeopsitda 和 personalbankingdao 标识的方框中的 property 属性)。上图还描述了 spring 容器不会尝试创建 与 daotemplate bean 定义相对应的bean 实例,因为他被标记为 abstract。 子 bean 定义从 父 bean 定义继承一下配置信息:注意:
抽象 bean 不能作为其他 bean 定义的依赖项,也就是说,不能使用 <property> 或 <constructor-arg> 元素来引用抽象 bean 。
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());
}
}
继承了什么
推荐阅读
-
02Spring基于xml的IOC配置--实例化Bean的三种方式
-
Spring 学习指南 第三章 bean的配置 (未完结)
-
spring 攻略 - 笔记- 第三章 Spring中Bean的配置(1)
-
解决Maven项目加载spring bean的配置xml文件会提示找不到问题
-
spring bean 的生命周期和配置源信息
-
spring如何使用命名空间p简化bean的配置
-
Spring概述 IOC容器和bean的配置
-
spring配置文件(spring的开发步骤;bean中的scope,init-method,destroy-method;bean的工厂静态方法实例化;工厂动态方法实例化)
-
Spring中的Bean配置
-
Spring 学习指南 第三章 bean的配置 (未完结)