超輕量級DI容器框架Google Guice與Spring框架的區別教程詳解及其demo程式碼片段分享
依賴注入,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等都是如此。
下邊是我做了一下對比
Spring | Guice | |
使用XML | 使用將類與類之間的關係隔離到xml中,由容器負責注入被呼叫的物件,因此叫做依賴注入 | 不使用xml,將類與類之間的關係隔離到Module中,聲名何處需要注入,由容器根據Module裡的描述,注入被呼叫的物件。 |
使用Annotation | 使用 支援自定義Annotation標註,對於相同的介面定義的物件引用,為它們標註上不同的自定義Annotation註釋,就可以達到同一個類裡邊的同一個介面的引用,注射給不同的實現,在Module裡用標註做區分,靈活性大大增加。 使用Annotation也未必是好事,範型等新特性也未必是好事,目前大多的伺服器均不支援jdk1.5,wls要9以前才支援,而目前的客戶由於價格原因也很少選用wls9的,至少我們做過的專案中都沒有。功能再強,客戶不需要,何用? |
|
執行效率 | 裝載spring配置檔案時,需解析xml,效率低,getBean效率也不高,不過使用環境不會涉及到getBean,只有生產環境的時候會用到getBean,在裝載spring應用程式的時候,已經完成全部的注射,所以這個低效率的問題不是問題。 | 使用Annotation,cglib, 效率高與spring最明顯的一個區別,spring是在裝載spring配置檔案的時候把該注入的地方都注入完,而Guice呢,則是在使用的時候去注射,執行效率和靈活性高。 |
類耦合度 | 耦合度低,強調類非侵入,以外部化的方式處理依賴關係,類裡邊是很乾淨的,在配置檔案裡做文章,對類的依賴性極低。 | 高,程式碼級的標註,DI標記@inject侵入程式碼中,耦合到了類層面上來,何止侵入,簡直侵略,程式碼耦合了過多guice的東西,大大背離了依賴注入的初衷,對於程式碼的可維護性,可讀性均不利 |
類編寫時 | 需要編寫xml,配置Bean,配置注入 | 只需宣告為@inject,等著被注入, 最後在統一的Module裡宣告注入方式 |
僅支援IOC | 否,spring目前已經涉獵很多部分 | 是,目前僅僅是個DI容器 |
是否易於程式碼重構 | 統一的xml配置入口,更改容易 | 配置工作是在Module裡進行,和spring異曲同功 |
支援多種注入方式 | 構造器,setter方法 | Field,構造器,setter方法 |
靈活性 |
1,如果同一個介面定義的引用需要注入不同的實現,就要編寫不同的Module,煩瑣 2,動態注入 如果你想注射的一個實現,你還未知呢,怎麼辦呢,spring是沒辦法,事先在配置檔案裡寫死的,而Guice就可以做到,就是說我想注射的這個物件我還不知道注射給誰呢,是在執行時才能得到的的這個介面的實現,所以這就大大提高了依賴注射的靈活性,動態注射。 |
|
與現有框架整合度 | 1, 高,眾多現有優秀的框架(如struts1.x等)均提供了spring的整合入口,而且spring已經不僅僅是依賴注入,包括眾多方面。 2, Spring也提供了對Hibernate等的整合,可大大簡化開發難度。 3, 提供對於orm,rmi,webservice等等介面眾多,體系龐大。 |
1,可以與現有框架整合,不過僅僅依靠一個效率稍高的DI,就想取代spring的地位,有點難度。 |
配置複雜度 | 在xml中定位類與類之間的關係,難度低 | 程式碼級定位類與類之間的關係,難度稍高 |
再借斧子的例子說一說spring與guice的區別
看下邊對於不同社會形態下一個人(java物件,呼叫者)需要一把斧子(java物件,被呼叫者)的例子:
(1),原始社會時,勞動社會基本沒有分工,需要斧子的人(呼叫者)只好自己去磨一把斧子,每個人擁有自己的斧子,如果把大家的石斧改為鐵斧,需要每個人都要學會磨鐵斧的本領,工作效率極低。
對應Java裡的情形是:java程式裡的呼叫者new一個被呼叫者的例項。類耦合度極高,修改維護煩瑣,效率極低。
(2),工業社會時,工廠出現,斧子不再由普通人完成,而由工廠生產,當人們需要斧子的時候,可以到工廠購買斧子,無需關心斧子是怎麼製造出來的,如果廢棄鐵斧為鋼斧,只需改變工廠的製造工藝即可,製作工藝是工廠決定的,工廠生產什麼斧子,工人們就得用什麼斧子。
對應的Java裡的情形是:Java程式的呼叫者可以以來簡單工廠建立被呼叫者,變化點被隔離到了簡單工廠裡,雖然耦合度降低,但是呼叫者會和工廠耦合,而且需要定位自己的工廠。
(3)近代工業社會,工廠蓬勃發展,人們需要什麼斧子,只需要提供一個斧子圖形,商家會按照你提供的圖形將你的斧子訂做好,送上門。
對應Java裡的情形:spring的依賴注入
(4)進入按需要分配社會,資訊進入現代化,人們不再去工廠購買斧子,不再拘泥於需要什麼斧子事先畫好什麼樣的圖形,只需要打個電話,描述一下需要什麼型別的斧子,或許想打造一個物美價廉的斧子,商家會根據市場零件的價格,計算出最優製作工藝,打造最適合的斧子送過來,更加資訊化,更加人性化。
對應Java裡的情形:基於描述的注入,動態的,靈活簡單的注入,如:Guice。
對於該不該使用Guice,我想也是仁者見仁,智者見智,就象好多論壇裡動不動有人會在那裡討論到底學Java還是學.net或者是使用eclipse還是Jbuilder的這類無聊話題,適合和滿足專案需求的,又能省工省力簡單的完成工作的,就是最好的。
在此拋磚引玉,大家有異議的地方歡迎和我討論。
相關推薦
超輕量級DI容器框架Google Guice與Spring框架的區別教程詳解及其demo程式碼片段分享
依賴注入,DI(Dependency Injection),它的作用自然不必多說,提及DI容器,例如spring,picoContainer,EJB容器等等,近日,google誕生了更輕巧的DI容器……Guice! 廢話不多講了,先看看Guice是如何實現注入的吧。 定
3dsmax2014的下載、安裝與註冊激活教程詳解
com cor 殺毒 系統 3dmax http 後退 tar 輸入 3dsmax2014的下載、安裝與註冊激活教程,雖然網上類似的教程文章不勝枚舉,但大多比較粗枝大葉,沒有詳細的步驟,尤其對於電腦小白來說,更是不易參考,今天我就教大家如何註冊破解3dsmax2014吧!
HTTP 中 GET 與 POST 的區別(詳解)
我們都知道GET和POST是HTTP請求的兩種基本方法,最直觀的區別就是GET把引數包含在URL中,POST通過request body傳遞引數。 很多權威網站總結出的他們的區別: GET在瀏覽器回退時是無害的,而POST會再次提交請求。 GET產生的URL地址可以被Bookmark,而POST不可以。
分享《深度學習與計算機視覺演算法原理框架應用》PDF《大資料架構詳解從資料獲取到深度學習》PDF +資料集
下載:https://pan.baidu.com/s/12-s95JrHek82tLRk3UQO_w 更多分享資料:https://www.cnblogs.com/javapythonstudy/ 《深度學習與計算機視覺 演算法原理、框架應用》PDF,帶書籤,347頁。《大資料架構詳解:從資料獲取到深度學
Spring框架介紹和IoC容器中Bean配置(Spring框架)
Spring框架整理第一發,Spring框架介紹,HelloWorld,IoC容器介紹,Bean配置 Spring概述 ①Spring為簡化企業級開發而生,使用Spring,JavaBean就可以實現很多以前要靠EJB才能實現的功能。同樣的功能,在EJB中要通過
activeMQ開發筆記,activeMQy與Spring框架整合
MQ開發其實很簡單: 本文以最新版本的ActiveMQ為例子,介紹了安裝和開發第一個MQ程式。 準備環境,JDK8,activeMQ 5.14.3,WIN7測試環境,Spring 4.3.4 首先是安裝 : 安裝MQ非常簡單,下載連結:https://activemq
【Spring MVC】DispatcherServlet詳解(容器初始化超詳細過程原始碼分析)
DispatcherServlet類相關的結構圖DispatcherServlet的初始化程式DispatcherServlet初始化了什麼,可以在其initStrategies()方法中知曉,這個方法如下: protected void initStrategies(App
MyBatis框架與Spring框架的結合方式
rop 功能 自動掃描 加載文件 bat tro java context drive <?xml version="1.0" encoding="UTF-8"?> <!-- 以下為配置文件 --> <beans xmlns="htt
php冒泡排序與快速排序實例詳解
lag ++ function 開始 ret light 記錄 php冒泡排序 php $a=array(‘3‘,‘8‘,‘1‘,‘4‘,‘11‘,‘7‘); print_r($a); $len = count($a); //從小到大 for($i=1;$i<$le
UML類圖與類的關系詳解--轉
position 好的 -a erp 生命 靜態 pan 雙向 單選 http://www.uml.org.cn/oobject/201104212.asp 原文地址 UML類圖與類的關系詳解 2011-04-21 來源:網絡
TCP協議的3次握手與4次揮手過程詳解
進行 發送數據 不存在 信息 隊列 協議 標識 方式 ar9 所謂三次握手(Three-Way Handshake)即建立TCP連接,就是指建立一個TCP連接時,需要客戶端和服務端總共發送3個包以確認連接的建立。所謂四次揮手(Four-Way Wavehand)即終止TCP
Spring框架——AOP(面向切面編程)詳解
通過 cts ssi 沒有 object 引入 集中 method 可能 1 AOP概述 ●AOP(Aspect-Oriented Programming,面向切面編程):是一種新的方法論,是對傳統 OOP(Object-Oriented Programming,面向對象
css-浮動與清除浮動的原理詳解(清除浮動的原理你知道嗎)
alt col ges mage all strong splay height http float元素A的特點: 脫離文檔流 靠向left或right float元素會和塊盒子重疊 準確來說,是塊盒子和A重疊,但塊盒子內容會浮動在A周圍 不會和inline元素重
TensorFlow框架(4)之CNN卷積神經網絡詳解
this map ets 多層神經網絡 本地 height its 網絡 操作 1. 卷積神經網絡 1.1 多層前饋神經網絡 多層前饋神經網絡是指在多層的神經網絡中,每層神經元與下一層神經元完全互連,神經元之間不存在同層連接,也不存在跨層連接的情況,如圖 11所示。
UML類圖與類的關系詳解
enc pla 分享 包含關系 影響 基礎 rem 建模 基本組件 UML類圖與類的關系詳解 在畫類圖的時候,理清類和類之間的關系是重點。類的關系有泛化(Generalization)、實現(Realizati
Flask(十)flash與前臺交互post詳解
ace for pos pre 視圖 bmi temp 做的 輸入 Project name :Flask_Plan templates:templates static:static POST提交方式,首先要有表單 老實去改模板文件吧。 查詢窗口我準備放在頁面最頂上,就改
PHP與Java集成開發詳解(一)
new 編程語言 到你 其中 web-inf request 測試 add 輸入 很久以前,有人從www上看到看到天空上一個很亮的亮點,它就是Java語言,與此同時,在另一個地方一位夢想家也看到了一個亮點,它就是PHP。 時間一天天過去,這兩個亮點也變得越來越亮,很快,它
【轉】Quartz.net持久化與集群部署開發詳解
疑惑 sum 常用 drive wid res net github hub 轉自:http://www.cnblogs.com/knowledgesea/p/5145239.html 序言 我前邊有幾篇文章有介紹過quartz的基本使用語法與類庫。但是他的執行計劃都是被寫
seekg()/seekp()與tellg()/tellp()的用法詳解
文件操作 一個 需要 message ret 開頭 origin 部分 rom 本文轉載於:http://blog.csdn.net/mafuli007/article/details/7314917 (在tcp的文件發送部分有應用) 對輸入流操作:seekg()與tell
hibernate框架學習筆記2:配置文件詳解
格式化 version validate ret root 主鍵生成策略 -m color 格式 實體類: package domain; public class Customer { private Long cust_id; priva