2011-09-15 48 views
0

我有一個關於春天的繼承問題: 比方說,我有一個類(豆)BraveKnight實現接口騎士。之後我宣佈這個bean與ID->騎士 xml文件,我試圖讓豆的參考:春繼承特點

Knight knight = (Knight) context.getBean("knight"); 

這是它的工作方式。但是爲什麼不能從bean的名字本身獲取bean引用:BraveKnight(爲什麼不能在沒有接口的情況下工作)?

BraveKnight knight = (BraveKnight) context.getBean("knight"); 
+0

*你的意思是不可能獲得bean引用*? –

回答

2

首先請使用:的

public <T> T getBean(String name, Class<T> requiredType) 

代替:

public Object getBean(String name) 

你會避免這個討厭的類型轉換。

其次,你爲什麼沒有接口工作的問題有點不明顯。我想你在BraveKnight沒有實現任何接口時會遇到某種問題。如果你想這樣做,你必須強制Spring使用CGLIB而不是動態代理機制。如果您在將Bean轉換爲BraveKnight時遇到ClassCastException的問題,這意味着Spring使用動態代理並實現了僅實現Knigh接口並且不直接擴展BraveKnigh的$ Proxy0類。無論您的問題是什麼,請嘗試更好地瞭解CGLIB和JDK動態代理機制,以便下次Spring將在您的對象中執行什麼操作時不會感到驚訝。
如果該答案與您的問題不符,請嘗試添加更多信息,堆棧跟蹤或解釋。

+0

爲什麼「討厭」?如何在方法簽名中鍵入類,這對於演員來說有很大的改進? – duffymo

+0

@duffymo因爲如果你犯了一個錯誤,演員會拋出ClassCastException。並調用getBean(String name,類 requiredType)將拋出BeanNotOfRequiredTypeException異常。沒有太大區別,但至少你會知道在bean創建過程中發生了一些不好的事情。另一件事是我不喜歡演員:D – goroncy

1

獲得使用其名稱豆: 「騎士」。您正在使用Spring bean名稱作爲密鑰。

如果你的問題是「爲什麼我不能用它的類型來查找bean」,答案是隻要只有一個這種類型的bean就可以。它被稱爲「自動裝配」。如果您添加註釋和一些必需的XML標記,Spring可以爲您做到這一點。

至於爲什麼它不會無界面地工作,誰說它沒有?你可以用Spring來連接具體的類類型。

更好的問題是「何時以及爲什麼我更喜歡在Spring中使用接口?」答案是,無論使用Spring還是不使用Spring,爲實現可能更改的情況設計接口都是一種很好的做法。它使Spring可以根據需要生成動態代理(例如,將事務添加到持久對象)。

+0

是的,我忘了說我使用AOP(周圍),我很好奇爲什麼我不被允許/不能訪問/運行未被覆蓋的BraveKnight方法(不在Knight界面中) – spauny

+0

因爲AOP通過從接口生成動態代理而工作。代理的執行是執行的。 – duffymo

0

您可以在沒有任何問題的情況下調用沒有應用程序上下文的接口。

只有當您使用AOP代理時,您才需要接口,在這種情況下,任何通過接口調用的對象引用都將導致異常。

0

如果可以使用BraveKnight作爲bean名稱,使其更容易理解映射,那麼可以使用它。 Craig Walls Spring In Action使用Knight作爲bean名稱,以清楚說明您的映射正在調用Knight的實現。

同樣,它不會與接口一起工作,因爲在java中你不能實例化一個接口。 直接映射到Knight完全一樣;

Knight knight = new Knight(); // This is illegal 

您將實例對騎士的實施,使其工作,例如:

Knight knight = new BraveKnight()//legal Implementation to Knight 

這就是爲什麼執行被用作背景文件的映射的原因。