《Spring攻略(第2版)》——1.13 繼承Bean配置
本節書摘來自異步社區《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
>
<property name="initial" value="100000" />
<property name="suffix" value="A" />
<property name="prefixGenerator" ref="datePrefixGenerator" />
</bean>
<bean
>
<property name="initial" value="100000" />
<property name="suffix" value="A" />
<property name="prefixGenerator" ref="datePrefixGenerator" />
</bean>
<bean
>
<property name="pattern" value="yyyyMMdd" />
</bean>
</beans>
為了避免重複相同的屬性,你可以用這些屬性集聲明一個基序列生成器。然後,兩個序列生成器可以從這個基生成器中繼承,這樣它們也就自動擁有了那些屬性集。如果子Bean和父Bean的class屬性相同,就不需要指定。
<beans ...>
<bean
>
<property name="initial" value="100000" />
<property name="suffix" value="A" />
<property name="prefixGenerator" ref="datePrefixGenerator" />
</bean>
<bean parent="baseSequenceGenerator" />
<bean parent="baseSequenceGenerator" />
...
</beans>
繼承的屬性可以由子Bean覆蓋。例如,你可以添加不同初始值的子序列生成器。
<beans ...>
<bean
>
<property name="initial" value="100000" />
<property name="suffix" value="A" />
<property name="prefixGenerator" ref="datePrefixGenerator" />
</bean>
<bean parent="baseSequenceGenerator">
<property name="initial" value="200000" />
</bean>
...
</beans>
現在,基序列生成器Bean可以恢複為Bean實例使用。如果你希望它僅作為模板,就必須將abstract屬性設置為true。以後Spring將不會實例化這個Bean。
<bean abstract="true"
>
...
</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 abstract="true">
<property name="initial" value="100000" />
</bean>
<bean abstract="true" parent="baseGenerator"
>
<property name="suffix" value="A" />
<property name="prefixGenerator" ref="datePrefixGenerator" />
</bean>
<bean parent="baseGenerator"
/>
<bean parent="baseSequenceGenerator" />
<bean parent="baseSequenceGenerator" />
<bean parent="baseSequenceGenerator"/>
...
</beans>
圖1-1顯示了這個生成器Bean層次結構的對象圖。
圖1-1 生成器Bean層次結構的對象圖
最後更新:2017-05-31 16:01:29