2011-04-13 209 views
2

我正在學習Spring使用Spring Recipes。截至目前,我明白我們可以使用Setter Injection或Injecting通過構造函數注入依賴關係。我的問題是,在現實世界的應用程序中哪些方法更經常使用,爲什麼?我知道它是一個主觀問題,但我不能想到比本網站更好的地方來獲得完美的見解。再次感謝。春天依賴注入

+0

這是一個3.方式:你可以直接注入字段。 – Ralph 2011-04-13 06:05:19

回答

4

構造函數注入優於setter注入,因爲它清楚地定義了所需的依賴關係,並強制您在創建類的實例之前提供它們。使用setter注入,調用者必須找出需要哪些依賴關係,並且可能導致調用者無法注入所有必需的依賴關係。

但是,有些情況下您需要使用setter注入,例如處理僅具有默認構造函數的對象,或者設置可能存在雙向關係的依賴項。

如果有疑問,請嘗試使用構造函數注入,並在需要時回退給setter。

+0

謝謝Andy .... – t0mcat 2011-04-13 02:53:22

+0

補充說的是,如果注入的構造函數注入的對象可以是'final'。 – Andrew 2013-02-09 12:13:08

0

我更喜歡構造函數注入自己。我自2005年以來一直在使用Spring。

+0

謝謝Duffymo .. – t0mcat 2011-04-13 02:55:28

2

其他的答案已經非常乾淨了,事實上,即使忘了設置一個字段,Constructor注入也更省力。 - 您可以不創建沒有該字段的實例。因此,這個陳述的一個建議可能是:爲必填字段使用構造函數注入,爲可選字段使用setter或字段注入。

,構造函數注入還有另外兩個影響:

  • 領域可以final - (我喜歡最後的領域,因爲化妝更容易理解)類
  • 你不能建立圈子。 (A.b和B.a) - Spring不能實例化這種構造。 (*從一個architetural點,我認爲這是構造器注入的職業,不是個騙子)

但在另一方面,如果你使用構造函數注入你必須寫一個比必要更多的代碼。

public class FieldInjection { 
    @Ressource //the same like @Autowired(required=true) 
    private MyService myService; 
} 

比要短得多:

public class MethodInjection {  
    private final MyService myService; 

    public MethodInjection(final MyService myService) { 
    assert(myService != null); 
    this.myService = myService; 
    } 
} 

其他答案的autors會恨我的發言。

個人相信,當你有一個類,即只作爲一個Spring bean(但不是沒有春天),那麼你可以使用字段注入而沒有安全疑慮! - 因爲如果Spring可以設置註釋爲@Ressource@Autowired(required=true)的所有字段,Spring只會將Bean放入其生命週期。正因爲如此,我更喜歡野外注射,因爲它使我更快(寫得少,少)。對於所有初始化的東西,我使用@PostConstruct。(當然你不能在構造函數中使用這些字段,而且你也不能將它們混合使用。) - 這使得我的應用程序與IOC容器相比更強大,而不是構造器注入,但這對我的用例不是問題。 - 可以看看EJB 3.1標準,它們根本沒有構造函數注入。

0

有每種方式都有優點和缺點。我認爲基於構造函數的依賴注入不太容易出錯,因爲你正在施加某些規則並告訴你的類它的方法需要哪些依賴。更重要的是,構造器注入強制執行初始化順序並防止循環依賴。通過setter注入,不清楚事物需要實例化的時間以及接線完成的順序。

另一方面,二傳手注射獲勝的原因有很多。如果構造器很簡單,少做或者什麼都不做,單元測試總是更容易。此外,並非所有類的方法都需要相同的依賴關係。如果你使用Spring容器來注入你的依賴項,那麼你並不總是要擔心這個,因爲如果你正確地配置它,Spring容器會自動爲你調用你的setter。