依賴注入是指在創建一個對象時,自動地創建它依賴的對象,並注入。
大家都知道有三種途徑來實現依賴注入,我這里總結一下這三種方式的優缺點:
1.構造方法注入:
優點:
- 在構造方法中體現出對其他類的依賴,一眼就能看出這個類需要其他那些類才能工作。
- 脫離了IOC框架,這個類仍然可以工作,POJO的概念。
- 一旦對象初始化成功了,這個對象的狀態肯定是正確的。
缺點:
- 構造函數會有很多參數(Bad smell)。
- 有些類是需要默認構造函數的,比如MVC框架的Controller類,一旦使用構造函數注入,就無法使用默認構造函數。
- 這個類里面的有些方法並不需要用到這些依賴(Bad smell)。
優點:
- 在對象的整個生命周期內,可以隨時動態的改變依賴。
- 非常靈活。
缺點:
- 對象在創建后,被設置依賴對象之前這段時間狀態是不對的。
- 不直觀,無法清晰地表示哪些屬性是必須的。
方法參數注入的意思是在創建對象后,通過自動調用某個方法來注入依賴。類似如下代碼。
public class MovieRecommender { private MovieCatalog movieCatalog; private CustomerPreferenceDao customerPreferenceDao; @Autowired public void prepare(MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) { this.movieCatalog = movieCatalog; this.customerPreferenceDao = customerPreferenceDao; } // ... }
這種方式介於Set方法注入和構造方法注入之間。比如說我們通常會用一個Init方法來接受依賴的參數。
這種方法可能不太常用,一般是只有一個方法依賴到注入的對象時用到,如果有多個方法依賴到注入的對象,還是比較傾向於使用構造方法注入。
優點:
- 比較靈活。
缺點:
- 新加入依賴時會破壞原有的方法簽名,如果這個方法已經被其他很多模塊用到就很麻煩。
- 與構造方法注入一樣,會有很多參數。
我個人很不傾向於在業務邏輯層中應用Autowired 或者是 Inject這樣的annotation(Attribute)來實現注入,
因為一旦脫離了IOC框架,代碼就無法重用了。
