Google Guice簡介

Guice可以緩和對於"工廠"和"new"關鍵字的依賴,將@Inject作爲new來看待。可能還是會用到一些和工廠相關的,但是代碼並不會直接依賴它們。甚至不客氣地可以說,Guice是core java裏面一個missing feature.

1.Motivation

首先,你並不想把所有的代碼都寫到一起。於是應這個形式,各個data,service,classes的連接方式也多種多樣。總是使用new,即使是工廠,總得還要寫一些set,remove方法進行初始化,將來要改代碼又得分別去代碼裏面改,比較混亂。

2.Dependency Injection (依賴注入)

也就是說將一個接口綁定到具體的類中,這樣的話,客戶端就不用關心具體的實現,只需要獲取相應的接口完成其服務就行了。

寫一個接口,裏面寫一些方法,然後寫一個實現類,將方法全部實現。使用的是Annotation,而不是傳統意義上的xml或者properties文件。

在實現類中,將一些需要使用到的Service作爲成員變量,然後在其構造函數中將這些變量初始化。這樣就可以通過構造函數的方式將dependencies傳給對象,讓對象初始化。

注意,需要在構造函數的上方加上@Inject的註解。

所有的操作都只跟接口有關,真正的實現類只是通過一個配置文件綁定好就行了。


3.使用

然後在真正的功能類中,想要使用的時候,先聲明一個Injector

Injector injector = Guice.createInjector(裏面放一個Module接口的實現類,或者其它抽象類比如AbstractModule的子實現類),Module類的實現類必須實現configure(Binder binder)方法,

即 
public class XXXModule extends AbstracModule{
     @Override
     public void configure(Binder binder){
     binder.bind(接口.class).to(實現類.class);    //不可以自己綁定自己
      xxx,這裏可以全部一起綁定了,相當於配置
     }
}

比如: bind.(Service.class).to(ServiceImpl.class);


注意:
1.Guice不允許綁定多個實現在一個接口上,所以實現可以寫很多個,但是真正配置的時候,只能綁定一個。這個是可以理解的,

試想,你在找實現類的時候總要有一種機制保證到底使用哪一種吧,不可能都使用。

2.綁定可以級聯,也就是bind(A).to(B); bind(B).to(C),那麼,在你調用A的時候,就會返回C的實例。

然後當你需要調用的時候,定義一個接口類型的變量,並且賦值

接口類 Service service= injector.getInstance(Service.class);

這樣就相當於把ServiceImpl的實例(也就是自己事先綁定好的實現)傳了過來,然後再調用裏面的方法


總結一下,意思就是,將一個ServiceImpl的實例和Service關聯起來,當向Guice請求獲取一個Service實例的時候,Guice就返回一個ServiceImpl的實例,然後就可以調用Service裏面的方法了。這樣就不用老是去new了,直接按照接口的定義使用就行了,關聯哪一個實現類,自己事先綁定好就是了。

1) @Singleton

使用Injector默認的配置的話,每次Guice都會返回一個新的實例,有時候可能並不希望總是這樣。很多時候需要使用單例模式(事實上我覺得很多估計都是單例吧。

a.就直接在實現類的類名前面一行加上一個@Singlton標註一下就行

比如
@Singleton
public class ServiceImpl implements Service{
              xxx
              xxx
}


b.還可以通過bind的statement來進行,比如bind(Service.class).to(ServiceImpl.class).in(Singleton.class);

注意:當然,ServiceImpl可以被多個Service綁定,所以,假如有2個不同的Service綁定了ServiceImpl,那麼就會創建2個ServiceImpl的實例。


2) @Inject

可以注入構造方法,主要的目的,應該是參數傳遞。往往實現類中會定義一些成員變量,這些成員變量很可能就是一些接口,然後通過注入構造函數將它們和一些實現類綁定。這樣同樣也是有個好處,代碼維護成本低。試想,你本來使用着一個框架,但是突然小組決定更換框架,這個時候使用注入只需要改一下綁定配置就行了。

反正知道這麼個原理就行,注入一些和服務有關係的,服務本身,或者將服務作爲參數的構造函數。然後綁定好,通過調用injector來獲取實例,使用服務。


4.Bindings

還是那個意思,injector的工作就是說將對象裝配起來,你請求獲取某個類型的實例,然後injector就會去找到它,並且返回給你。

怎樣創建bindings呢? 寫一個module類,繼承AbstractModule抽象類,重寫它的configure方法。然後在這個方法裏面,你可以調用bind()方法來進行綁定。在你進行綁定的時候,它會給你提示,如果你的接口和實現類不匹配的話,就會報錯。一旦這個module類創建好了,你就可以在創建injectot的時候將它作爲參數了。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章