3.7 Spring 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定义从父级继承 作用域,构造函数参数值,属性值和方法覆盖,并具有添加新值的选项。 您指定的任何作用域,初始化方法,销毁方法和/或static工厂方法设置将覆盖相应的父设置。

剩下的设置是 always 取自子定义:depends on autowire模式依赖性检查 singleton lazy init

前面的示例通过使用abstract属性将父bean定义显式标记为抽象。 如果父定义没有指定类,则需要将父bean定义明确标记为`abstract',如下所示:

<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不能自己实例化,因为它是不完整的,它也被显式标记为“抽象”。 当定义是这样的“抽象”时,它只能用作纯模板bean定义,用来作为子定义的父定义。 试图使用这样的抽象父bean,通过引用它作为另一个bean的ref属性或使用父bean id执行显式的getBean()调用,返回一个错误。 同样,容器的内部preInstantiateSingletons()方法忽略定义为抽象的bean定义。

[Note]
ApplicationContext默认实例化所有单例。 因此,重要的是(至少对于单例bean)如果你有一个(父)bean定义,你打算只使用作为一个模板,并且这个定义指定一个类,你必须确保设置 abstract 属性 为 true ,否则应用程序上下文将实际(尝试)预实例化abstract bean。

results matching ""

    No results matching ""