初次認識Guice

梧桐雨—168發表於2008-03-19
從網站上看到了有人提起這個框架——Guice,google名下的產物——一個彼Spring快的DI容器,興趣使然,馬上到http://code.google.com/p/google-guice/上去看了看,發現居然是Bob Lee這位大仙的傑作,還猶豫什麼,download下來試試!

      恩,從哪裡試起呢?還是老規矩,碰到新的東西就來驗證我們經典的例子——Hello World!

      這個東西說是DI,居然沒有.xml或者.properties檔案,老天它用的是該死的Annotation,很好,要是大家也想嘗試的話統統5.0或者以上的幹活。安裝好環境,開始動手!可是從哪裡開始呢?既然說是DI容器,那好,我們先把我們的程式準備好,然後再看它把各個需要的東西怎麼Inject。

      借鑑一下Spring開發手冊裡的例子吧,稍微改改(無聊的人不要罵這個程式,因為它太簡單,我都想罵!)。既然是要列印,我們先來一個列印的服務介面:

public interface PrintService
{
    
public void print(String str);
}

很好,再來一個它的實現:

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”,而是該死的列印服務!好了,Client和我們的列印服務是分開的,我不知道Guice會怎麼把列印服務在Client需要的時候Inject進來。不管怎麼做,一個test是應該有的:

import junit.framework.TestCase;

public class testClient extends TestCase
{

    
public void testPrintString()
     {
         Client client
=new Client();
         client.printString();
     }

}

好了,試試看,應該是紅色的條子。廢話,Client在這裡根本不知道該死的列印服務在哪裡。那麼尋找列印服務就是Guice的事情了。

      讓我們看看Guice是怎麼進行Inject的。我們想要Client在使用的時候找到列印服務,那麼我們應該在Client需要的時候將其Inject進去,這樣的話我們需要寫一個類似於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方法,這個方法可以充當Inject點,然後我們在這個方法上面來一個Annotation——@Inject”,這就是告訴Guice應該在哪裡Inject我們需要的列印服務。

      好了,我們下面要做的就是把PrintService和我們的實現動態的繫結起來(介面程式設計,好主意)。在Guice裡,我們需要實現一個叫做Module的介面,Guice將一個binder傳遞給你的Module,然後你的Module將介面和它的實現繫結起來。讓我們來試一下:

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);
     }

}

在我們需要列印服務的時候,Guice會自動建立一個PrintServiceImpl的例項給我們。OK,接下來就是如何注入的問題了,我們需要在test中實現:

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的工作流程是這樣的:

首先將自己建立的Module傳給Guice.createInjector(),Guice會為你的Module建立一個binder,你的Module利用這個binder來實現各種繫結,然後在Guice會建立一個Injector出來,我們就可以利用這個Injector來Inject我們的服務了。

    Guice將DI這個概念完完全全的詮釋了出來,使我們在編寫的應用的時候不必去考慮具體的實現在哪裡,Guice會為你動態的繫結並且Inject的。很好使的框架,很有意思,以後繼續關注!!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13270562/viewspace-211673/,如需轉載,請註明出處,否則將追究法律責任。