程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 超輕量級DI容器框架Google Guice與Spring框架的區別

超輕量級DI容器框架Google Guice與Spring框架的區別

編輯:關於JAVA

依賴注入,DI(Dependency Injection),它的作用自然不必多說,提及DI容器,例如spring,picoContainer,EJB容器等等,近日,google誕生了更輕巧的DI容器……Guice!

廢話不多講了,先看看Guice是如何實現注入的吧。

定義一個簡單的service接口和它的實現吧:

package com.zuidaima.demo.guice;  
public interface MyService ... {  
 void myMethod();  
}
package com.zuidaima.demo.guice;  
      
 public class MyServiceImpl implements MyService ... {  
 public void myMethod() ...{  
 System.out.println("Hello,World!");  
 }  
}

以上是最普通的接口和其實現,沒什麼可說的。

定義一個測試類,這個類裡邊包括service對象的一個引用,這個對象是需要Guice進行注入的

package com.zuidaima.demo.guice;  
      
import com.google.inject.Inject;  
 public class Client ... {  
 MyService service;  
 @Inject //告訴容器,這裡的service對象的引用,需要進行注入  
 void setService(MyService service) ...{ //這裡的方法名字可以任意定義  
 this.service=service;  
 }  
 public void myMethod() ...{  
 service.myMethod();  
 }  
}

這裡除了加了一個@Inject,和Spring的配置沒有任何的區別,@Inject,是表示對容器說,這裡的service需要注射,等到運行的時候,容器會拿來一個實例給service,完成注射的過程。

定義Guice的Module文件 告訴容器如何進行注入

package com.zuidaima.demo.guice;  
      
import com.google.inject.Binder;  
 import com.google.inject.Module;  
 import com.google.inject.Scopes;  
      
 public class MyModule implements Module ... {  
 public void configure(Binder binder) ...{ binder.bind(MyService.class).to(MyServiceImpl.class).in(Scopes.SINGLETON);  
 // 這句代碼的意思是說:運行時動態的將MyServiceImpl對象賦給MyService定義的對象,而且這個對象是單例的。  
 }  
}

創建測試類

package com.zuidaima.demo.guice;  
      
import com.google.inject.Guice;  
import com.google.inject.Injector;  
      
 public class Test ... {  
      
 public static void main(String[] args) ...{  
MyModule module=new MyModule();// 定義注射規則  
Injector injector=Guice.createInjector(module);// 根據注射規則,生成注射者  
 Client client=new Client();  
injector.injectMembers(client);// 注射者將需要注射的bean,按照規則,把client這個客戶端進行注射  
 client.myMethod();   
}  
}

運行測試類,控制台輸出:Hello,World!

完成注入過程

下面看看Guice還有哪些其它的使用特性。

1,如果在實現你確定MyService定義的對象,就要被注射為MyServiceImpl而不是其它的實現類的話,可以在MyService接口加上@ImplementedBy(MyServiceImpl.class)

package com.zuidaima.demo.guice;  
      
import com.google.inject.ImplementedBy;  
      
@ImplementedBy(MyServiceImpl. class )  
 // 我總覺得這樣有點背離了依賴注入的初衷了   
 public interface MyService ... {  
 void myMethod();  
}

這樣的話,在MyModule裡的configure方法中就可以不加任何東西,容器就會自動注射給MyServiceImpl對象。

2,可以對Field進行注解式注入

在Client.java中也可以把這個@Inject標注在MyService  service;的前邊,如:@Inject MyService service;

3,可使用自定義Annotation標注。

package com.zuidaima.demo.guice;  
      
 import java.lang.annotation.ElementType;  
 import java.lang.annotation.Retention;  
 import java.lang.annotation.RetentionPolicy;  
 import java.lang.annotation.Target;  
      
 import com.google.inject.BindingAnnotation;  
      
@Retention(RetentionPolicy.RUNTIME)  
@Target( ... { ElementType.FIELD, ElementType.PARAMETER })  
@BindingAnnotation
 public @ interface MyInterface ... {  
       
}

那麼Client.java需要改為

package com.zuidaima.demo.guice;  
      
 import com.google.inject.Inject;  
      
 public class Client ... {  
      
 @Inject @MyInterface MyService service;  
       
 void setService(MyService service) ...{ // 這裡的方法名字可以任意定義  
 this.service=service;  
 }  
      
 public void myMethod() ...{  
 service.myMethod();  
 }  
}

MyModule.java中的configure方法內容需改為:

binder.bind(MyService.class).annotatedWith(MyInterface.class).to(

MyServiceImpl.class).in(Scopes.SINGLETON);

意思是說對於標注為MyInterface的MyService定義的對象進行注入

進行Annotation標注的成員(Field,method,argument等)進行自定義Annotation標注,該成員既擁有該屬性,可以在運行,根據這些成員的不同屬性,做一些不同的事情 例如:spring的AspectJ,xdoclet等都是如此。

下邊是我做了一下對比

Guice與Spring的對比

再借斧子的例子說一說spring與guice的區別

看下邊對於不同社會形態下一個人(java對象,調用者)需要一把斧子(java對象,被調用者)的例子:

(1),原始社會時,勞動社會基本沒有分工,需要斧子的人(調用者)只好自己去磨一把斧子,每個人擁有自己的斧子,如果把大家的石斧改為鐵斧,需要每個人都要學會磨鐵斧的本領,工作效率極低。

對應Java裡的情形是:java程序裡的調用者new一個被調用者的實例。類耦合度極高,修改維護煩瑣,效率極低。

(2),工業社會時,工廠出現,斧子不再由普通人完成,而由工廠生產,當人們需要斧子的時候,可以到工廠購買斧子,無需關心斧子是怎麼制造出來的,如果廢棄鐵斧為鋼斧,只需改變工廠的制造工藝即可,制作工藝是工廠決定的,工廠生產什麼斧子,工人們就得用什麼斧子。

對應的Java裡的情形是:Java程序的調用者可以以來簡單工廠創建被調用者,變化點被隔離到了簡單工廠裡,雖然耦合度降低,但是調用者會和工廠耦合,而且需要定位自己的工廠。

(3)近代工業社會,工廠蓬勃發展,人們需要什麼斧子,只需要提供一個斧子圖形,商家會按照你提供的圖形將你的斧子訂做好,送上門。

對應Java裡的情形:spring的依賴注入

(4)進入按需要分配社會,信息進入現代化,人們不再去工廠購買斧子,不再拘泥於需要什麼斧子事先畫好什麼樣的圖形,只需要打個電話,描述一下需要什麼類型的斧子,或許想打造一個物美價廉的斧子,商家會根據市場零件的價格,計算出最優制作工藝,打造最適合的斧子送過來,更加信息化,更加人性化。

對應Java裡的情形:基於描述的注入,動態的,靈活簡單的注入,如:Guice。

對於該不該使用Guice,我想也是仁者見仁,智者見智,就象好多論壇裡動不動有人會在那裡討論到底學Java還是學.net或者是使用eclipse還是Jbuilder的這類無聊話題,適合和滿足項目需求的,又能省工省力簡單的完成工作的,就是最好的。

在此拋磚引玉,大家有異議的地方歡迎和我討論。

代碼下載地址:http://www.zuidaima.com/share/1759689106541568.htm

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved