依賴注入的主要類型
- 構(gòu)造器注入
- Setter注入
- 接口注入(不推薦)
- Filed變量注入(不推薦)
Setter注入 battle 構(gòu)造器注入
-
構(gòu)造器注入
Spring4.X以后鼓勵(lì)使用構(gòu)造器注入,構(gòu)造器注入的組件通常需要在構(gòu)造的時(shí)候完成初始化。即弄慰,一般依賴的組件以及組件依賴的外部輸入等第美,都需要我們?cè)跇?gòu)造的時(shí)候完成初始化。
實(shí)現(xiàn)業(yè)務(wù)組件時(shí)陆爽,如果該對(duì)象是一個(gè)不變的對(duì)象什往,構(gòu)造器注入確保了這個(gè)對(duì)象不為空。即慌闭,當(dāng)依賴一個(gè)對(duì)象時(shí)别威,這個(gè)對(duì)象必須存在,因此不能為空驴剔。哪怕這個(gè)對(duì)象不存在或者實(shí)在是為空的話省古,也可以通過(guò)ObjectProvider(Spring 4.X引入,一種類型安全的方式)的getIfAvailable()方法來(lái)進(jìn)行返回仔拟。
-
構(gòu)造器注入的優(yōu)點(diǎn):
- 構(gòu)造器注入可以把一般都不會(huì)變更的字段衫樊,賦值的字段定義為final,無(wú)論是從線程安全的角度還是未來(lái)可變性的角度來(lái)說(shuō)都是比較友好的利花。通常習(xí)慣在面向?qū)ο髸r(shí),對(duì)象都是不變的载佳,即一旦創(chuàng)建好就不要變炒事,如果這個(gè)對(duì)象要變更,可以把這個(gè)對(duì)象重新生成一份蔫慧,使用新生成的這個(gè)對(duì)象挠乳,而不是老的對(duì)象。
- 如果用多個(gè)Java Bean的時(shí)候姑躲,會(huì)減少一些代碼睡扬,主要是指有Setter/getter方法。
- 構(gòu)造器注入就有這個(gè)先后順序的約束約束黍析,一般就是根據(jù)Java語(yǔ)法就是誰(shuí)在前卖怜,誰(shuí)在后,進(jìn)行初始化順序的阐枣,不能由客戶端任意修改马靠。
-
構(gòu)造器注入如果參數(shù)過(guò)多,代碼看起來(lái)不是很友好蔼两,一般需要做一些重構(gòu)甩鳄,換句話說(shuō)就是不應(yīng)該把太多的職責(zé)放到一個(gè)類里,一個(gè)方法里不應(yīng)該有太多的輸入额划。
//構(gòu)造器注入 private DependencyA dependencyA; private DependencyB dependencyB; private DependencyC dependencyC; @Autowired public DependencyInjection(DependencyA dependencyA, DependencyB dependencyB, DependencyC dependencyC) { this.dependencyA = dependencyA; this.dependencyB = dependencyB; this.dependencyC = dependencyC; }
-
Setter注入
Spring3.X鼓勵(lì)使用妙啃,Spring 4.X以后認(rèn)為是可選的注入方式,Setter注入字段本身是可變化的俊戳,所以對(duì)象本身或注入的內(nèi)容可以為空揖赴。如@Autowired注解默認(rèn)會(huì)把相關(guān)的依賴強(qiáng)行注入馆匿,如果依賴不存在,根據(jù)屬性required(默認(rèn)為true)設(shè)置為false來(lái)進(jìn)行控制储笑。
//不為age屬性傳遞任何參數(shù)甜熔,下面的示例也會(huì)成功運(yùn)行,但是name屬性則需要一個(gè)參數(shù) public class Student { private Integer age; private String name; @Autowired(required=false) public void SetAge(Integer age) { this.age = age; } @Autowired public void SetName(String name) { this.name = name; } }
Setter注入的優(yōu)缺點(diǎn)
- Setter方法通常能夠讓對(duì)象變得更加可配置或者在某個(gè)時(shí)候可以被重新注入突倍。換言之腔稀,依賴注入的時(shí)候,也許是第一次注入羽历,那么是再次注入的話焊虏,也不會(huì)有一個(gè)新的對(duì)象的變化。
- Setter注入對(duì)具有默認(rèn)值的對(duì)象非常有效秕磷,意味著并非所有屬性都需要在運(yùn)行時(shí)提供诵闭。對(duì)象里有個(gè)默認(rèn)值,Setter方法可以覆蓋掉這個(gè)初始值澎嚣。
- Setter中的order無(wú)法確認(rèn)疏尿,比如Student對(duì)象有個(gè)SetAge/SetName兩個(gè)方法,至于哪個(gè)先易桃,哪個(gè)后并沒(méi)有一定的規(guī)約來(lái)進(jìn)行約束褥琐。
- Setter的注入,只有當(dāng)對(duì)象是需要被注入的時(shí)候它才會(huì)幫助我們注入依賴晤郑,而不是在初始化的時(shí)候就注入
//Setter注入 private DependencyA dependencyA; private DependencyB dependencyB; private DependencyC dependencyC; @Autowired public void setDependencyA(DependencyA dependencyA) { this.dependencyA = dependencyA; } @Autowired public void setDependencyB(DependencyB dependencyB) { this.dependencyB = dependencyB; } @Autowired(required=false) public void setDependencyC(DependencyC dependencyC) { this.dependencyC = dependencyC; }