1.1 依賴注入
? ? ????應(yīng)用中大量存在A對(duì)象需要調(diào)用B對(duì)象方法的情形顷帖,這種情形被稱為依賴庭猩,即A對(duì)象依賴B對(duì)象窟她。
? ? ????通常有如下兩種方式來(lái)實(shí)現(xiàn)依賴:
? ? ????(1)原始做法:調(diào)用者主動(dòng)創(chuàng)建被依賴對(duì)象蔼水,然后再調(diào)用被依賴對(duì)象的方法;
? ? ????(2)簡(jiǎn)單工廠模式:調(diào)用者先找到被依賴對(duì)象的工廠趴腋,然后主動(dòng)通過(guò)工廠去獲取被依賴對(duì)象,最后再調(diào)用被依賴對(duì)象的方法优炬。(此方試遵守如下原則:①調(diào)用者面向被依賴對(duì)象的接口編程;②將被依賴對(duì)象的創(chuàng)建交給工廠完成蠢护;③調(diào)用者通過(guò)工廠來(lái)獲得被依賴組件。)
????????兩種注入方式的弊端:
? ? ????原始做法:調(diào)用者主動(dòng)創(chuàng)建對(duì)象葵硕,導(dǎo)致調(diào)用者與被依賴對(duì)象實(shí)現(xiàn)類的硬編碼耦合,不利于項(xiàng)目升級(jí)和維護(hù)懈凹。
? ? ????簡(jiǎn)單工廠模式:調(diào)用組件需要主動(dòng)通過(guò)工廠去獲取被依賴對(duì)象,這就會(huì)帶來(lái)調(diào)用組件與被依賴對(duì)象工廠的耦合介评。
? ? ????Spring方式實(shí)現(xiàn)依賴:
? ? ????程序無(wú)須使用new關(guān)鍵字調(diào)用構(gòu)造器去創(chuàng)建對(duì)象爬舰,所有的Java對(duì)象都可交給Spring容器去創(chuàng)建寒瓦;當(dāng)調(diào)用者需要調(diào)用被依賴對(duì)象的方法時(shí)情屹,調(diào)用者無(wú)須主動(dòng)獲取被依賴對(duì)象杂腰,只要等待Spring容器注入即可。
? ? ????綜上所述颈墅,Spring實(shí)現(xiàn)依賴的方式雾袱,彌補(bǔ)了前兩種方式實(shí)現(xiàn)依賴所存在的不足恤筛。
? ? ????使用Spring框架之后芹橡,調(diào)用者獲取被依賴對(duì)象的方式由原來(lái)的主動(dòng)獲取,變成了被動(dòng)接受林说,這種方式被稱為控制反轉(zhuǎn)(Inversion of Control,IoC)腿箩。從Spring容器的角度來(lái)看,Spring容器負(fù)責(zé)將被依賴對(duì)象賦值給調(diào)用者的成員變量——相當(dāng)于為調(diào)用者注入他所依賴的實(shí)例珠移,因此這種方式又被稱為依賴注入(Dependency Injection,DI)钧惧。
1.2 Spring依賴注入
????????Spring框架的核心機(jī)制有兩個(gè):
????????(1)Spring容器作為超級(jí)大工廠,負(fù)責(zé)創(chuàng)建浓瞪、管理所有的Java對(duì)象,這些Java對(duì)象被稱為Bean乾颁;
????????(2)Spring容器管理容器中Bean之間的依賴關(guān)系,Spring使用一種被稱為“依賴注入”的方式來(lái)管理Bean之間的依賴關(guān)系钮孵。
? ? ????Spring使用配置文件或注解配置Bean,在配置文件中巴席,Spring配置Bean實(shí)例通常制定如下屬性:
????????id:指定該Bean唯一的表示,Spring根據(jù)id屬性值來(lái)管理Bean,程序通過(guò)id屬性值來(lái)訪問(wèn)該Bean實(shí)例荧库;
????????class:指定該Bean的實(shí)現(xiàn)類,此處不可用接口分衫,必須使用實(shí)現(xiàn)類,Spring容器會(huì)使用XML解析器讀取該屬性值蚪战,并利用反射來(lái)創(chuàng)建該實(shí)現(xiàn)類的實(shí)例。
? ? ????Spring依賴注入的兩種方式:
? ? ????(1)設(shè)值注入:IoC容器使用成員變量的setter方法來(lái)注入被依賴對(duì)象邀桑;
? ? ????(2)構(gòu)造注入:IoC容器使用構(gòu)造器來(lái)注入被依賴對(duì)象。
1.2.1 設(shè)值注入
? ? ????Bean與Bean之間的依賴關(guān)系由Spring管理壁畸,Spring采用setter方法為目標(biāo)Bean注入所依賴的Bean,這種方式被稱為設(shè)值注入捏萍。
1.2.2 構(gòu)造注入
? ? ????Bean與Bean之間的依賴關(guān)系由Spring管理,Spring在構(gòu)造實(shí)例時(shí)令杈,同時(shí)為其完成了依賴關(guān)系的初始化。這種利用構(gòu)造器來(lái)設(shè)置依賴關(guān)系的方式这揣,被稱為構(gòu)造注入。
1.3 兩種注入方式的對(duì)比
? ? ????兩種注入方式?jīng)]有絕對(duì)的好壞给赞,只是適應(yīng)的場(chǎng)景有所不同。
? ? ????設(shè)值注入具有如下優(yōu)勢(shì):
? ? ????(1)與傳統(tǒng)的JavaBean的寫法更相似片迅,程序開發(fā)人員更容易理解、接受柑蛇。通過(guò)setter方法設(shè)定依賴關(guān)系顯得更加直觀、自然耻台;
? ? ????(2)對(duì)于復(fù)雜的依賴關(guān)系,如果采用構(gòu)造注入盆耽,會(huì)導(dǎo)致構(gòu)造器過(guò)于臃腫扼菠,難以閱讀坝咐。Spring在創(chuàng)建Bean實(shí)例時(shí)循榆,需要同時(shí)實(shí)例化其依賴的全部實(shí)例墨坚,因而導(dǎo)致性能下降。而使用設(shè)值注入泽篮,則能避免這些問(wèn)題。
? ? ????(3)尤其是在某些成員變量可選的情況下帽撑,多參數(shù)的構(gòu)造器更加笨重。
? ? ????構(gòu)造注入具有如下優(yōu)勢(shì):
? ? ????(1)構(gòu)造注入可以在構(gòu)造器中決定依賴關(guān)系的注入順序油狂,優(yōu)先依賴的優(yōu)先注入寸癌。
? ? ????(2)對(duì)于依賴關(guān)系無(wú)須變化的Bean专筷,構(gòu)造注入更有用處蒸苇。因?yàn)闆]有setter方法,所有的依賴關(guān)系全部在構(gòu)造器內(nèi)設(shè)定溪烤。因此味咳,無(wú)須擔(dān)心后續(xù)的代碼對(duì)依賴關(guān)系產(chǎn)生破壞檬嘀。
? ? ????(3)依賴關(guān)系只能在構(gòu)造器內(nèi)設(shè)定,則只有組件的創(chuàng)建者才能改變組件的依賴關(guān)系鸳兽。對(duì)組件的調(diào)用者而言,組件內(nèi)部的依賴關(guān)系完全透明揍异,更符合高內(nèi)聚的原則。
? ? ????因此衷掷,建議采用一設(shè)值注入為主,構(gòu)造注入為輔的注入策略戚嗅。