1.7. Bean Definition Inheritance
一个bean定义包含大量的配置信息,构造器参数,property 的值,还有容器指定的信息,例如初始化(initialization )方法,静态工厂方法名等等。子bean可以继承并重写父类的配置数据,也可以增加需要的属性。
好处:节省大量输入。
如果以编程方式使用ApplicationContext接口,则子bean定义由ChildBeanDefinition类表示,但我们基本不会在这个level操作。我们的操作都在bean声明定义中例如 ClassPathXmlApplicationContext,用XML方式的话,需要指定parent属性,例如
<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兼容,就是接受父类的属性值, 个人理解就是比如name的属性为String,那么子bean也是,如果理解有误,希望看到的指正一下。
子bean定义,可以继承父bean 的scope、constructor 参数values、property 的values、override方法,也可以增加新的value选项。所有的scope, initialization method, destroy method, or static
factory method settings都会覆盖父bean。
其余的设置取决于子定义:例如 depends on, autowire mode, dependency check, singleton, and lazy init.
上面的例子中,父bean定义通过 abstract 属性指定了true属性,且指定了 class ,如果,没有指定一个class,则必须将父bean定义显式标定为 abstract (***疑问??两个例子中都指定了abstract为true,到底显式指定是个啥意思,两者不同只是没指定class而已***),例如
<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的和不完整的,尝试单独使用都会返回error,容器内部用于 预实例化的方法 preInstantiateSingletons() 也会忽略abstract类型的bean。
Tips:ApplicationContext 会预实例化所有的单例bean。