從協(xié)作到合約 參考讀物 關(guān)于依靠項(xiàng)插入的經(jīng)典介紹,請參閱 Martin Fowler 的 “Inversion of Control Containers and the Dependency Injection Pattern”。關(guān)于使用 Spring 的依靠項(xiàng)插入的更多內(nèi)容,請參閱 Professional java Development with the Spring Framework。這兩者的鏈接都在 參考資料 中。 針對這篇文章的目的,可以把依靠項(xiàng)插入想像成對象和對象的執(zhí)行環(huán)境之間的合約。對象(執(zhí)行 ResourceConsumer、 Collaborator 和 ServiceClient 的其中一個(gè)角色或全部角色)同意不出去搜索自己需要的資源、它與之協(xié)作的合作伙伴或它使用的服務(wù)。相反,對象提供一種機(jī)制,讓這些依靠項(xiàng)可以提供給它。接下來,執(zhí)行環(huán)境同意在對象需要它的依靠項(xiàng)之前,向?qū)ο筇峁┧械囊揽宽?xiàng)。
解析依靠項(xiàng)的方法在不同的場景中各有不同。例如,在單元測試用例中,對象的執(zhí)行環(huán)境是測試用例本身,所以測試設(shè)置代碼有責(zé)任直接滿足依靠項(xiàng)。在集成測試或應(yīng)用程序在生產(chǎn)環(huán)境時(shí),代理 負(fù)責(zé)尋找滿足對象依靠項(xiàng)的資源,并把它們傳遞給對象。代理的角色通常是由輕量級容器扮演的,例如 Spring 框架。不管依靠項(xiàng)是如何解析的,被配置的對象通常不知道這類細(xì)節(jié)。在第二個(gè)示例中,它可能還不知道代理的存在。
代理(例如 Spring 框架)有四個(gè)要害職責(zé),在整篇文章中我將不斷提到這些職責(zé),它們是:
確定對象需要配置(通常因?yàn)閷ο髣倓倓?chuàng)建)
確定對象的依靠項(xiàng)
發(fā)現(xiàn)滿足這些依靠項(xiàng)的對象
用對象的依靠項(xiàng)對它進(jìn)行配置
從下面的各種依靠項(xiàng)插入解決方案可以看出,解決這些職責(zé)有多種策略。 使用 Spring 進(jìn)行依靠項(xiàng)插入
在標(biāo)準(zhǔn)的 Spring 部署中,Spring 容器同時(shí)負(fù)責(zé)創(chuàng)建和配置核心應(yīng)用程序?qū)ο螅ǚQ為 bean)。因?yàn)槿萜骷葎?chuàng)建對象,又扮演代理的角色,所以對 Spring 容器來說,確定 bean 已經(jīng)創(chuàng)建而且需要配置是件輕而易舉的小事。通過查詢應(yīng)用程序的元模型,可以確定 bean 的依靠項(xiàng),元模型通常是在 Spring 的配置文件中用 xml 表示的。
滿足 bean 的依靠項(xiàng)的對象是容器治理的其他 bean。容器充當(dāng)這些 bean 的倉庫,所以可以用名稱查詢它們(或者在需要的時(shí)候創(chuàng)建)。最后,容器用新 bean 的依靠項(xiàng)對其進(jìn)行配置。這通常是通過 setter 插入完成的(調(diào)用新 bean 的 setter 方法,把依靠項(xiàng)作為參數(shù)傳遞進(jìn)去),雖然 Spring 支持其他形式的插入,例如構(gòu)造函數(shù)插入和查詢方法插入(請參閱 參考資料 學(xué)習(xí)關(guān)于使用 Spring 進(jìn)行依靠項(xiàng)插入的更多內(nèi)容。)