1. 程式人生 > >超輕量級DI容器框架Google Guice與Spring框架的區別教程詳解及其demo程式碼片段分享

超輕量級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等都是如此。

下邊是我做了一下對比

Guice與Spring的對比
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 GuiceSpring框架區別教程及其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開發筆記,activeMQySpring框架整合

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提交方式,首先要有表單 老實去改模板文件吧。 查詢窗口我準備放在頁面最頂上,就改

PHPJava集成開發(一)

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