天天看點

Spring-Context之九:在bean定義中使用繼承

定義bean時有個abstract屬性,可以設定為true或false,預設為false。

這裡定義了一個叫elepahnt的animal bean,有4條腿,它與其他bean不同之處是abstract屬性為true。這意味着什麼?意味着這個bean不能被執行個體化,不能通過ApplicationContext.getBean()的方式來擷取到該bean,也不能使用ref屬性引用這個bean。否則會抛出BeanIsAbstractException的異常。

你可能會問?坑爹那?聲明一個bean不能被執行個體化,那有何用?

當然有用,Spring架構開發者也不是一幫吃飽了沒事幹的人,設計一些沒用的功能出來。

這要配合着parent屬性來用。

這裡有兩個bean,一個是animal,指定legs是4,另一個是monkey,通過parent的屬性指向animal,指定name為dudu。聰明的讀者可能已經猜出來了,parent屬性就是子bean可以繼承父bean中的屬性,并且在子bean中可以重載對應的屬性。雖然我們沒顯式的指定monkey的legs為4,其實它已經從父bean animal中繼承了這個屬性。這樣的好處是如果在定義大量bean時,發先大量bean存在重複屬性定義時,可以抽取一個抽象bean出來,實作這些重複的屬性定義,讓其他bean都使用parent屬性指向這個抽象bean。這樣可以大大簡化bean的配置。

除了使用parent直接引用父bean的class外,另外也可以使用自定義的class。

Monkey.java

這樣smartMonkey自動繼承了父bean中的legs屬性,同時它的class類型也是一個新類型。

有人可能要問了,子bean的class與父bean中的class一定要是繼承關系嗎?答案是否定的。

請看這個修改後的Monkey class,其本身并未從Animal繼承。

然後還配置同樣的bean。

依然能夠正常工作,并且smartMonkey中的legs還是4。

這說明了Spring中使用parent繼承父bean中的屬性并不需要子bean和父bean的class在一個繼承樹上。父bean更像一個模闆,子bean能夠自動使用父bean中的配置而已。唯一需要注意的是在父bean中定義的屬性在子bean中都要存在。

那可能有人就有個大膽的猜想了,可不可以定義一個沒有class類型的父bean那?這個bean反正不能執行個體化,隻用來讓子bean繼承屬性。答案是肯定的。

上面的定義依然可以工作。

多說一點,parent也支援對集合屬性的繼承。比如在父bean中定義了一個屬性為List或Map,子bean中也能繼承到該List或Map,更強大的是子bean還可以對List或Map進行合并。

在子bean中使用的map元素上使用merge=“true”就可以和父bean中的map條目進行合并。如果指定為false則不會合并,隻會使用子bean中定義的map條目。