在spring中,可以通過使applicationContext.xml調用構造函數來初始化bean,也可以在bean上設置屬性。這兩種方法之間的折衷是什麼?有一個構造函數(它在一種方法中強制執行它需要的所有內容)或更好地擁有所有屬性(這使得您可以靈活地僅在單元測試時選擇性地進行注入)更好嗎?什麼是初始化bean的最佳方式?
什麼(在編寫一個使用構造函數來建立它的初始狀態的bean,或使用屬性和可能的afterProperties()方法)之間進行權衡?
在spring中,可以通過使applicationContext.xml調用構造函數來初始化bean,也可以在bean上設置屬性。這兩種方法之間的折衷是什麼?有一個構造函數(它在一種方法中強制執行它需要的所有內容)或更好地擁有所有屬性(這使得您可以靈活地僅在單元測試時選擇性地進行注入)更好嗎?什麼是初始化bean的最佳方式?
什麼(在編寫一個使用構造函數來建立它的初始狀態的bean,或使用屬性和可能的afterProperties()方法)之間進行權衡?
我不確定是否有「最佳」的方式來初始化一個bean。我認爲每個人都有優點和缺點,並且根據情況,其中一個或另一個可能是合適的。這當然不是一個詳盡的清單,但這裏有一些需要考慮的事項。
使用構造函數可以讓你擁有一個不可變的bean。如果你可以將它們放在你的設計中,那麼不可變的物體是很好的。它們不需要在線程之間進行復制,序列化訪問或其他特殊處理。如果你有setter,你的對象是不可改變的。使用構造函數還可確保對象正確初始化。構造函數完成後,該對象是有效的。如果您的對象要求使用setter來初始化它,那麼可能會有一個無效的對象。
另一方面,使用構造函數通常會導致伸縮問題。通常情況下,您需要許多不同的構造函數,其中大部分將是另一個構造函數的超集。通常這些都是爲了方便。例如:
public class Person {
public Person(String name) { ... }
public Person(String name, String phone) { ... }
public Person(String name, String phone, String email) { ... }
}
一種可以替代的,我非常喜歡的就是所謂的「增強型」建設者在JavaOne會議上通過喬希布洛赫呈現模式。你可以在他的書「Effective Java,Second Edition」中看到這一點。如果您查看模式的使用方式,它也將解決您的「afterProperties」方法問題。構建器模式將確保對象正確初始化。
這是一個額外的博客文章討論的模式:http://www.screaming-penguin.com/node/7598
我不知道這個適合你的春天的要求,但在一般情況下,我是建設者的大風扇。
IMO構造函數注入的主要優點是它兼容不變性。但是,如果一個類有超過3個依賴關係,則需要提供一個構造函數,該構造函數需要大量的參數,這很笨拙。
當使用setter-injection時,我更喜歡使用@PostConstruct
註釋來標識初始化方法。這涉及到比您提到的afterProperties()
方法更鬆散的耦合到Spring框架(實際上,我認爲它是afterPropertiesSet()
)。另一個選項是<bean>
元素的init方法屬性。
我不知道你當前使用的版本,但如果它是Spring 2.5,你也可以考慮在某些情況下使用@Autowired註解。這種粗糙只適用於其他bean的引用,而不適用於字符串等,如lycony的示例。
它爲您節省了創建setter和/或構造函數的負擔以及大量的配置。 一個小例子:
public class MyPersonBean {
@Autowired
private PersonManager personManager;
public void doSomething() {
this.personManager.doSomething();
}
}
而且在你的配置文件:
<context:annotation-config/>
自動裝配由類型來完成的,所以如果你有類型的PersonManager的豆,它會在註釋字段注入它。如果你有這種類型的,你可以使用@Qualifier註解告訴他們分開的豆類...
您可以找到有關在
自動裝配更多的信息,我開始與部件組合使用@Autowired - 在我以前的項目中掃描,我必須說我擺脫了超過90%的Spring配置文件。
的權衡:
構造: 優點: 可以很簡單,ESP。具有三個或更少的屬性來初始化。 一次性,無/極少額外配置擔心。
缺點: 多個構造必須幾種情況 構造函數是不可繼承的創建,因此類必須調用super(),並提供重複的構造,使以前的行爲。
安裝人: 優點: 孩子們繼承了設置者,所以屬性可以很容易地被覆蓋以影響施工後的行爲。 每一個二傳手必須顯式調用每一個屬性: 多個屬性可以以統一的方式頭也不擡不同的方法簽名(JavaBean規範)
缺點指定。 導致某些具有大量明確設置的屬性的類。
您還可以使用@Resource
自動裝配,而不是@Autowired
,這個工作有點像自動裝配綽號,所以你不必擔心,如果有更多的豆類與同類型(OFC你也可以處理與@Qualifier
,但我只會建議描述一個bean的特性)。這取決於你的使用情況,哪種方式最好,因此你必須根據你的情況對它進行評估,然後再決定。
+1 - 真的很好的答案 – 2009-03-11 02:36:20