一个bean定义可包含不少配置信息,包括构造函数参数,属性值和容器特定信息例如初始化方法、静态工厂方法名等等。一个子bean定义从父bean定义继承配置数据。子bean定义能够根据须要覆盖一些值或者增长其它值。使用父、子bean定义能够节省许多代码输入。实际上,这是模版的一种形式。spring
若是编程的方式使用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的属性值。ide
子bean定义从父bean定义继承做用域、构造函数参数值、属性值和方法覆盖,并添加新值。任何对做用域、初始化方法、销毁方法和静态工厂方法的设置会覆盖相关父定义的设置。函数
------其它的设置老是从子定义获取,包括:依赖关系、自动装配模式、依赖关系检查、单例、懒加载初始化。---------code
上例中经过使用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。作用域