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