IoC容器7——bean定义继承

原创
2017/06/30 15:22
阅读数 72

bean定义继承

一个bean定义可包含很多配置信息,包括构造函数参数,属性值和容器特定信息例如初始化方法、静态工厂方法名等等。一个子bean定义从父bean定义继承配置数据。子bean定义可以根据需要覆盖一些值或者增加其它值。使用父、子bean定义可以节省许多代码输入。实际上,这是模版的一种形式。

如果编程的方式使用ApplicationContext接口,子bean定义被表示为ChildBeanDefinition类。大多数用户不在这个级别上使用它,而是以声明的方式配置bean定义在(例如)ClassPathXmlApplicationContext中。当使用基于XML的配置元数据,使用parent属性表明是一个子bean定义,设置这个属性的值为parent 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>

如果没有指定class属性,子bean定义使用父bean定义的class属性,但是也可以覆盖。在后一种情况下,子bean的类必须于父bean的类兼容,即它必须可以接受父bean的属性值。

子bean定义从父bean定义继承作用域、构造函数参数值、属性值和方法覆盖,并添加新值。任何对作用域、初始化方法、销毁方法和静态工厂方法的设置会覆盖相关父定义的设置。

------其它的设置总是从子定义获取,包括:依赖关系、自动装配模式、依赖关系检查、单例、懒加载初始化。---------

上例中通过使用abstract属性明确指出了父bean定义是抽象的。如果父定义没有指定class属性,就需要明确的标记bean定义是抽象的。例如:

<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由于不完整而不能被实例化,它也需要明确的标记为abstract。当一个bean定义是抽象的,它仅仅能用作纯模版bean定义,作为子定义的父定义。尝试通过引用它作为另一个bean的引用属性或使用id进行显示的getBean()调用来使用一个抽象的父bean会返回一个错误。相似的,容器内部的preInstantiateSingletons()方法会忽略抽象的bean定义。

ApplicationContext默认预实例化所有的singleton。因此,如果有一个(父)bean定义打算仅当作模版使用并且这个bean定义指定了类,保证设置abstract属性为true是非常重要的(至少对singleton bean),否则应用上下文会尝试预实例化抽象bean。

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部