《Spring攻略(第2版)》——1.13 继承Bean配置

    xiaoxiao2024-05-07  9

    本节书摘来自异步社区《Spring攻略(第2版)》一书中的第1章,第1.13节,作者: 【美】Gary Mak , Josh Long , Daniel Rubio著,更多章节内容可以访问云栖社区“异步社区”公众号查看

    1.13 继承Bean配置

    1.13.1 问题在Spring IoC容器中配置Bean时,你可能拥有超过一个共享某些公用配置的Bean,比如属性和元素中的属性。你常常必须为多个Bean重复这些配置。

    1.13.2 解决方案Spring允许你提取公用的Bean配置组成一个父Bean。从父Bean继承而来的Bean称作子Bean。子Bean从父Bean继承Bean配置,包括Bean属性和元素中的属性,避免重复配置。子Bean在必要时也可以覆盖继承的配置。

    父Bean可以作为配置模板,也可以同时作为Bean的一个实例。但是,如果你希望父Bean只作为模板而不能检索,必须将abstract设置为true,要求Spring不要实例化这个Bean。

    必须注意,并不是所有在父元素中定义的属性都将被继承。例如,autowire 和dependency-check属性不会从父Bean中继承。如果需要了解哪些属性从父Bean继承,而哪些不能,请参见关于Bean继承的Spring文档。

    1.13.3 工作原理假定你必须添加一个新的序列生成器实例,初始值和后缀与现有的生成器相同。

    <beans ...>    <bean id="sequenceGenerator"      class="com.apress.springrecipes.sequence.SequenceGenerator">      <property name="initial" value="100000" />      <property name="suffix" value="A" />      <property name="prefixGenerator" ref="datePrefixGenerator" />    </bean>    <bean id="sequenceGenerator1"      class="com.apress.springrecipes.sequence.SequenceGenerator">      <property name="initial" value="100000" />      <property name="suffix" value="A" />      <property name="prefixGenerator" ref="datePrefixGenerator" />    </bean>    <bean id="datePrefixGenerator"      class="com.apress.springrecipes.sequence.DatePrefixGenerator">      <property name="pattern" value="yyyyMMdd" />    </bean> </beans>

    为了避免重复相同的属性,你可以用这些属性集声明一个基序列生成器。然后,两个序列生成器可以从这个基生成器中继承,这样它们也就自动拥有了那些属性集。如果子Bean和父Bean的class属性相同,就不需要指定。

    <beans ...>    <bean id="baseSequenceGenerator"      class="com.apress.springrecipes.sequence.SequenceGenerator">      <property name="initial" value="100000" />      <property name="suffix" value="A" />      <property name="prefixGenerator" ref="datePrefixGenerator" />    </bean>    <bean id="sequenceGenerator" parent="baseSequenceGenerator" />    <bean id="sequenceGenerator1" parent="baseSequenceGenerator" />    ... </beans>

    继承的属性可以由子Bean覆盖。例如,你可以添加不同初始值的子序列生成器。

    <beans ...>    <bean id="baseSequenceGenerator"      class="com.apress.springrecipes.sequence.SequenceGenerator">      <property name="initial" value="100000" />      <property name="suffix" value="A" />      <property name="prefixGenerator" ref="datePrefixGenerator" />    </bean>    <bean id="sequenceGenerator2" parent="baseSequenceGenerator">      <property name="initial" value="200000" />    </bean>    ... </beans>

    现在,基序列生成器Bean可以恢复为Bean实例使用。如果你希望它仅作为模板,就必须将abstract属性设置为true。以后Spring将不会实例化这个Bean。

    <bean id="baseSequenceGenerator" abstract="true"    class="com.apress.springrecipes.sequence.SequenceGenerator">    ... </bean>

    你也可以忽略父Bean的类,让子Bean指定自己的类,特别是在父Bean与子Bean不在同一类层次结构但是共享同名属性的时候。在这种情况下,父Bean的abstract属性必须设置为true,因为父Bean不能实例化。例如,我们添加另一个也有initial属性的Reverse Generator类。

    package com.apress.springrecipes.sequence; public class ReverseGenerator {    private int initial;    public void setInitial(int initial) {      this.initial = initial;    } }

    现在,SequenceGenerator和ReverseGenerator不会扩展相同的基类,也就是说,它们不在相同的类层次结构中,但是具有同名的属性:initial。为了提取公共的initial属性,你需要一个没有定义class属性的父Bean——baseGenerator。

    <beans ...>    <bean id="baseGenerator" abstract="true">      <property name="initial" value="100000" />    </bean>    <bean id="baseSequenceGenerator" abstract="true" parent="baseGenerator"      class="com.apress.springrecipes.sequence.SequenceGenerator">      <property name="suffix" value="A" />      <property name="prefixGenerator" ref="datePrefixGenerator" />    </bean>    <bean id="reverseGenerator" parent="baseGenerator"      class="com.apress.springrecipes.sequence.ReverseGenerator" /> <bean id="sequenceGenerator" parent="baseSequenceGenerator" />    <bean id="sequenceGenerator1" parent="baseSequenceGenerator" />    <bean id="sequenceGenerator2" parent="baseSequenceGenerator"/>    ... </beans>

    图1-1显示了这个生成器Bean层次结构的对象图。

    图1-1 生成器Bean层次结构的对象图

    相关资源:敏捷开发V1.0.pptx
    最新回复(0)