2012-10-16 79 views
25

我正在看書Pro Spring 3。它有一段讓我很困惑。該段是關於春季自動裝配的。下面是摘錄:何時使用春季自動裝訂

在大多數情況下,回答了是否應使用 自動裝配的問題肯定是「不!」自動裝配可以節省您的時間,在小 應用,但在許多情況下,它會導致到不好的做法,並且在大型應用中是不靈活的。使用byName似乎是一個很好的想法,但它可能會導致您爲類指定人造屬性 名稱,以便您可以利用自動裝配功能。 Spring背後的整個想法是,你可以創建你的類,你如何 喜歡並有你春天的工作,而不是其他的方式...

...對於任何非平凡的應用程序,避開自動裝配在所有 費用。

我一直在創建的應用程序中使用@Autowired標籤。有人可以解釋它有什麼問題以及我應該使用什麼?

我如何處理大部分的東西現在是一個小例子:

@Service("snippetService") 
public class SnippetService { 

    @Autowired 
    private TestService testService; 

    public Snippet getSnippet() { 
     return testService.getSnippet(); 
    } 
}  

是使用自動裝配類似這樣的「錯誤」還是我失去了一些東西?

+0

我不是Spring用戶,但我熟悉Guice和CDI。這些框架基本上只是自動裝配;對於每個帶註釋的注射部位,框架都會根據類型和任何存在的限定符去找到它可以注入的東西,然後注入它。人們使用這種方法構建了非常大的應用程序;我在一個工作。我不相信他們遇到了Spring autowire-phobes所預言的問題。 –

+0

一個警告,但:這些框架不autowire的意義上'autowire =「byType」'。如果像@mrembisz所說的那樣,這篇文章是特別警告的,那麼Guice和CDI的經驗就沒有關係。 –

回答

23

我相信這裏有兩件事困惑。在本章中,「自動裝配」的意思是將bean標記爲自動檢測和注入依賴關係。這可以通過設置「autowire」bean屬性來實現。

這實際上是反對使用@Autowired其中您明確地指示字段或設置程序的依賴項注入。

看看這裏:http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-factory-autowire

來解釋它,假設你有

public class SnippetService { 

    private TestService testService; 

    public Snippet getSnippet() { 
     return testService.getSnippet(); 
    } 

    public void setTestService(TestService testService) { 
     this.testService = testService; 
    } 
} 

如果你定義一個bean:

<bean class="mypackage.SnippetService" autowire="byType"/> 

春天會嘗試注入匹配的類型,TestService在這種情況下豆,通過調用setTestService二傳手。即使你沒有使用@Autowired。這確實是危險的,因爲一些制定者可能並不打算在春季被召喚。

如果您設置autowire =「no」,則不會注入任何東西,除非使用@Autowired,@Resource,@Inject進行標記。

+1

這樣做更有意義。我剛剛出現這種情況。我想讀取屬性文件中的值並將它們注入到bean中。只有這樣才能弄清楚在我的應用程序啓動時如何做到這一點,就是用XML連接bean(並注入屬性)。我最終使用了「byName」屬性(因爲bean也被標記爲@Component)然後在將bean注入另一個類時使用@Autowired @Qualifier(「nameIChose」)。這是我用XML連線寫的唯一一個bean。 – Marvo

+0

非常感謝您的澄清! – geoffreydv

+0

我發現自動裝配有用的情況下,我有一個工廠bean製造另一個bean(其實現類名在系統屬性中描述,所以我不能定義XML中的所有接線)。我通常更喜歡讓我的佈線明確,但;如果事情明確,它可以大大簡化長期維護工作。 –

3

你有什麼問題沒有問題,特別是如果你是從一個實現TestService開始的。正如Johan提到的那樣,最好使用@javax.annotation.Resource,如果需要(例如使用nametype屬性),它也允許您更具體。

+2

不推薦使用'@ Qualifier'來支持'@ Resource' –

+0

這是正確的,謝謝指出。 –

+0

由於Spring IoC容器實現了JSR 250,這是否會使@Resource始終與@Autowired相反?編輯:顯然它取決於(驚喜!)有趣的論壇帖子http://forum.springsource.org/showthread.php?48563-Autowired-and-Resource-difference – dardo

2

我在這裏看到的唯一問題是您失去了一點控制權。例如,假設您的應用配置中有兩個或更多個TestService實例,並且您想使用其中的一個實例。擁有Autowire使得比使用配置XML爲您注入更復雜。這就是你的書試圖指出的,即在這種需求更頻繁的大型應用程序中,它變得困難/棘手。

如果你沒有這種情況,我認爲它很好。

+1

但是你在這種情況下所做的是使用@Qualifier註釋來指示你想要哪些bean。 – Marvo

+0

我沒有說你不能那樣做。我的意思是說:配置文件是爲了在外部注入和使用依賴關係。通過使用'annotations',我們將它帶入實現類本身。在較大的應用程序中這變得困難/棘手。 –

+1

我認爲這是主觀的。我發現無需維護大型繁瑣的XML文件變得更加困難。如果需要一個特定接口的新實現,我將不得不更改XML和類;自動裝配,我會簡單地替換這個類。少一個變化,少一個可能的錯誤。 – Marvo

0

如果您使用基於構造函數的自動裝配,尤其是在使協作者私有最終的情況下,通過XML自動裝配是非常安全和有用的。

作者說,當我在幾年前的一個非常大的spring 2.5項目中做了上述工作時,我感到非常震驚。 (當時註釋支持在JBoss中不起作用)