Spring IOC 之Bean定义的继承

一个Bean的定义可以包含大量的配置信息,包括构造器参数、属性值以及容器规范信息,比如初始化方法、静态工厂方法名字等等。一子bean的定义可以从父bean的定义中继承配置数据信息。子bean定义可以覆盖一些值只要需要也可以增加其他的值。使用父bean定义和子bean定义可以接受大量的类型说明。实际上,这也是一种形式的模板。

如果你在程序中使用一个ApplicationContext接口,子bean定义就是通过ChildBeanDefinition类来表示的。大部分用户不会在这个级别来处理它们,它们会在比如ClassPathXMLApplicationContext这样的类中进行配置bean的声明。当你使用基于XML的配置信息,你通过使用parent属性来表示一个子bean,通过这个属性可以指明父bean的值。

<bean id="inheritedTestBean" abstract="true"
 class="org.springframework.beans.TestBean">
 <property name="name" value="parent"/>
 <property name="age" value="1"/>
</bean>
<bean id="inheritsWithDifferentClass"
 class="org.springframework.beans.DerivedTestBean"
 parent="inheritedTestBean" init-method="initialize">
 <property name="name" value="override"/>
 <!-- the age property value of 1 will be inherited from parent -->
</bean>

如果一个子bean的定义中什么都没有指明的话,那么它就会使用父bean的定义,但是也它可以覆盖父类。在后一种的情形中,子bean类必须和父bean是兼容的,也即是说,它必须接受父bean的属性值。

一个子bean从父bean中继承了构造器参数值、属性值可以覆盖父的方法也可以根据需要选择区增加心得之。任何你指明的的初始化方法、销毁方法或者是静态工厂方法设置都会覆盖相关的父类设置。

剩下的设置就会直接从之类中获取:depends on、awire mode、dependency check、singlethon、scope、lazy init。

前面的例子明确的标记了父bean定义是一个抽象类通过使用abstruct属性。如果父定义没有指明一个类、这个表明bean定义是一个abstruct是必须的,正如下面一样:

<bean id="inheritedTestBeanWithoutClass" abstract="true">
 <property name="name" value="parent"/>
 <property name="age" value="1"/>
</bean>
<bean id="inheritsWithClass" class="org.springframework.beans.DerivedTestBean"
 parent="inheritedTestBeanWithoutClass" init-method="initialize">
 <property name="name" value="override"/>
 <!-- age will inherit the value of 1 from the parent bean definition-->
</bean>

父bean不能够被自己实例化因为它是不完整的而且它被显示的标记为abstruct。当一个bean定义像这样是abstruct的,它作为一个充当子定义的父定义的纯净的模板是可复用的。如果试着去使用这个abstruct父bean,通过引用它作为其他bean的属性或者使用父bean的id显示的调用getBean()就会返回一个错误,相似的是,容器的内部的preInstantiateSingletons()方法会忽略那些定义为abstract的bean的定义。

注意:ApplicationContext默认情况会下提前实例化所有的单例。也就是说,如果你有一个打算用来作为一个模板的bean定义而且这个定义指明了一个类,你必须确认abstract属性时true,要不然的话ApplicationContext会提前实例化这个 abstract的bean。
posted on 2015-01-29 22:55  叼烟斗的纤夫  阅读(1416)  评论(0编辑  收藏  举报