一個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。作用域