隨著 Guice 的最初發行版慢慢塵埃落定,將它和 Spring IoC,尤其是和 Spring JavaConfig 進行的比較也隨之浮出水面。Guice 和 JavaConfig 采取了兩種不同的方式使用 Java Annotations 將 IoC 配置放入代碼。
目前 Spring JavaConfig 發布了 1.0 Milestone 1 版本,它和 Guice 的基本想法是一致的——把配置從 XML 移至 Annotation 是一種更好的做法,因為這樣使得配置信息與代碼更為緊密。Tapestry 的 IoC 容器也是根據同樣的想法設計的。
JavaConfig 和 Guice 的背景極其相似。事實上,Bob Lee 是這樣敘述它們的歷史的:
此外,我還想說一個有點意思的小故事:Guice 最開始的時候和 Spring JavaConfig 看起來非常像——這並不奇怪,因為 Rod 一年前向我展示了 Spring JavaConfig(而六個月前我又讓他看了 Guice)。正如使用 JavaConfig 一樣,你得顯式地寫 Java 代碼來連接你的對象。我從一開始就引入 @Inject 做為檢查外部代碼按照你的安排調用所有的 setters 的一種可選方式。而自打我們有了 @Inject,我開始問,我們為什麼還需要顯式地編寫對象連接代碼呢?於是很快我們就有大家今天所知道的 Guice。
關於 Guice 和 JavaConfig 區別的帖子有不少。Debasish Ghosh 恰如其分地總結到:
Guice 和 Spring 之間最主要的區別,可以歸結為它們看待依賴關系和配置的哲學之間的差異。Spring 宣揚的是非侵入性的方式,以一種完全外部化的方式來對待對象依賴關系。在 Spring 裡,你可以使用 XML、Spring JavaConfig 或者 Groovy-Spring DSL 來連接對象依賴關系,也可以使用其它的方案,如 Spring-annotations。但是,不管你用的是什麼技術,依賴關系總是被外部化的。
另一方面,Guice 卻把配置做為你的應用程序模型的首要對象來看待,允許它們存在於你的領域模型代碼中。我們使用 Guice 模塊來說明需要注入什麼東西,然後使用 annotations 來指明需要在什麼注入。你可以使用注入來標記(annotate)類本深(通過 @Inject annotation)。缺點則是(如果你使者麼認為的話)你必須在你的領域模型中引入 com.google.inject.*。但它通過元數據編程(metadata programming)來確保了目標的方向性,以及注入的顯式語義。
在這些文章的回帖中,你可以發現,在這兩個框架之間做選擇的時候,最值得注意的就是它們設計哲學的區別。你會希望依賴注入和代碼靠得有多近呢?如果使用 Guice,你的代碼將和容器緊密耦合在一起,這樣做有些人喜歡,有些人反感。Guice 號稱自己的速度更快,但值得注意的是,Spring IoC 容器(不管是 JavaConfig 還是其它)支持多種鉤子,而 Guice 並沒有提供。Spring 為大家帶來的不僅僅是 IoC,而 Guice 並不打算解決那些大問題。