???? 從網(wǎng)站上看到了有人提起這個框架——Guice,google名下的產(chǎn)物——一個彼Spring快的DI容器,興趣使然,馬上到http://code.google.com/p/google-guice/上去看了看,發(fā)現(xiàn)居然是Bob Lee這位大仙的杰作,還猶豫什么,download下來試試!
???? 恩,從哪里試起呢?還是老規(guī)矩,碰到新的東西就來驗證我們經(jīng)典的例子——Hello World!
???? 這個東西說是DI,居然沒有.xml或者.properties文件,老天它用的是該死的Annotation,很好,要是大家也想嘗試的話統(tǒng)統(tǒng)5.0或者以上的干活。安裝好環(huán)境,開始動手!可是從哪里開始呢?既然說是DI容器,那好,我們先把我們的程序準備好,然后再看它把各個需要的東西怎么Inject。
???? 借鑒一下Spring開發(fā)手冊里的例子吧,稍微改改(無聊的人不要罵這個程序,因為它太簡單,我都想罵!)。既然是要打印,我們先來一個打印的服務(wù)接口:
?
public
?
interface
?PrintService
{
????
public
?
void
?print(String?str);
}
?
很好,再來一個它的實現(xiàn):
?
public
?
class
?PrintServiceImpl?
implements
?PrintService
{
????
public
?
void
?print(String?str)
????{
????????System.out.print(str);
????}
}
?
然后呢?一個打印客戶Client:
?
public
?
class
?Client
{
????
private
?String?str
=
"
Hello?world
"
;
????
private
?PrintService?service;
????
void
?printString()
????{
????????service.print(str);
????}
}
?
看到了么?這次Inject的不是那個該死的字符串“Hello World”,而是該死的打印服務(wù)!好了,Client和我們的打印服務(wù)是分開的,我不知道Guice會怎么把打印服務(wù)在Client需要的時候Inject進來。不管怎么做,一個test是應(yīng)該有的:
?
import
?junit.framework.TestCase;
public
?
class
?testClient?
extends
?TestCase
{
????
public
?
void
?testPrintString()
????{
????????Client?client
=
new
?Client();
????????client.printString();
????}
}
?
好了,試試看,應(yīng)該是紅色的條子。廢話,Client在這里根本不知道該死的打印服務(wù)在哪里。那么尋找打印服務(wù)就是Guice的事情了。
???? 讓我們看看Guice是怎么進行Inject的。我們想要Client在使用的時候找到打印服務(wù),那么我們應(yīng)該在Client需要的時候?qū)⑵銲nject進去,這樣的話我們需要寫一個類似于setter的東西來建造一個Inject點,那么我們在Client里添加些東西:
?
import com.google.inject.Inject;
public
?
class
?Client
{
????
private
?String?str
=
"
Hello?world
"
;
????
private
?PrintService?service;
??? @Inject
????
void
?injectPrintService(PrintService?service)
????{
????????
this
.service
=
service;
????}
????
void
?printString()
????{
????????service.print(str);
????}
}
?
我們寫入了一個injectPrintService方法,這個方法可以充當(dāng)Inject點,然后我們在這個方法上面來一個Annotation——“@Inject”,這就是告訴Guice應(yīng)該在哪里Inject我們需要的打印服務(wù)。
???? 好了,我們下面要做的就是把PrintService和我們的實現(xiàn)動態(tài)的綁定起來(接口編程,好主意)。在Guice里,我們需要實現(xiàn)一個叫做Module的接口,Guice將一個binder傳遞給你的Module,然后你的Module將接口和它的實現(xiàn)綁定起來。讓我們來試一下:
?
import
?com.google.inject.Binder;
import
?com.google.inject.Module;
public
?
class
?MyModule?
implements
?Module
{
????
public
?
void
?configure(Binder?binder)
????{
????????binder.bind(PrintService.
class
).to(PrintServiceImpl.
class
);
????}
}
?
在我們需要打印服務(wù)的時候,Guice會自動創(chuàng)建一個PrintServiceImpl的實例給我們。OK,接下來就是如何注入的問題了,我們需要在test中實現(xiàn):
?
import
?junit.framework.TestCase;
import
?com.google.inject.
*
;
public
?
class
?testClient?
extends
?TestCase
{
????
public
?
void
?testPrintString()
????{
????????MyModule?mo
=
new
?MyModule();
????????Injector?in
=
Guice.createInjector(mo);
????????Client?client
=
new
?Client();
????????in.injectMembers(client);
????????client.printString();
????}
}
?
完了!一個全新的Hello world將要被打印出來了。
???? Guice的工作流程是這樣的:
首先將自己創(chuàng)建的Module傳給Guice.createInjector(),Guice會為你的Module創(chuàng)建一個binder,你的Module利用這個binder來實現(xiàn)各種綁定,然后在Guice會創(chuàng)建一個Injector出來,我們就可以利用這個Injector來Inject我們的服務(wù)了。
???Guice將DI這個概念完完全全的詮釋了出來,使我們在編寫的應(yīng)用的時候不必去考慮具體的實現(xiàn)在哪里,Guice會為你動態(tài)的綁定并且Inject的。很好使的框架,很有意思,以后繼續(xù)關(guān)注!!