大年初一上完廟拜完年後,繼續未完的Guice研究。它是藉由起風前的相遇Blog看到的,是Google出品的有別於Spring的一個輕型的IoC container。而我正是因為報名了OSDC 2010,其Semilar主要內容是Google的Android,經Google才藉由該Blog得知Guice。經練習後,發現也不難用,過程也發生一個小問題得已解決。

  不脫一個介面再對映一個實作,然後藉由一個媒介對映陳年飯粒,而必須用JDK 5.0來煮,因為Guice多以Annotation為主:

Interface:

public interface MyService {
    public String getServiceName();
}

Implement:

public class MyServiceImpl implements MyService {
    @Inject
    public MyServiceImpl() { }
    public String getServiceName() {
        return "Happy New Year!";
    }
}

  本例是不需要建構子,是為之後講@Inject所需。接著是寫一個繼承AbstractModule的類別,作用相當於Spring的ApplicationContext.xml為介面和實作做mapping。

public class MyModule extends AbstractModule{
    @Override
    protected void configure() {
        bind(MyService.class).to( MyServiceImpl.class );
    }
}

  Override configure這method,使用bind(介面).to(實作)綁定。完全免使用configuration file。使用方式如下:

Injector injector = Guice.createInjector(new MyModule());
MyService myService = injector.getInstance(MyService.class );
System.out.println(myService.getServiceName());

 

  藉由Guice的createInjector取得Injector,而其傳入的參數需繼承AbstractModule,因此可以依需求實作不同的Module。而Injector的角色就如同Spring的Context物件了。目前Spring 3據稱也有類似Guice的作法。另外,Spring裡的bean配置需要get/set進行DI,而在Guice則是透過方才說的@Inject取得,也可透過同一個AbstractModule去做bind to,以下是摘自Google的飯粒:

private final CreditCardProcessor processor;
private final TransactionLog transactionLog;
@Inject
public MyServiceImpl(CreditCardProcessor processor, TransactionLog transactionLog) {
    this.processor = processor;
    this.transactionLog = transactionLog;
}

  在Implement的Construction進行DI。

public class MyModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(TransactionLog.class).to(DatabaseTransactionLog.class);
        bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class);
        bind(MyService.class).to(MyServiceImpl.class);
    }
}

  在Guice的createInjector,就對Implement class進行Inject,因此configure method裡,先注入的要先bind to。


  我使用Maven去建構Guice,結果出現一個Exception如下:

Exception in thread "main" java.lang.NoClassDefFoundError:[Lorg/aopalliance/intercept/MethodInterceptor;

  經追查,Guice和Spring一樣都有引用aopalliance這個jar檔。是故其depency設定如下:

<dependency>
          <groupId>aopalliance</groupId>
          <artifactId>aopalliance</artifactId>
          <version>1.0</version>
</dependency>

  而Guice在Maven預設repository雖然有設,其artifactID為com.google.inject,版本為2.0。而Google的repository顯然較新,版本為2.0.1,其repository為:

<repository>
          <id>guice-maven</id>
          <name>guice-maven</name>
          <url>http://guice-maven.googlecode.com/svn/trunk</url>
</repository>

  所需要的jar按http://code.google.com/p/google-guice/的建議,其dependency設定如下:

      <dependency>
          <groupId>com.google.code.guice</groupId>
          <artifactId>guice</artifactId>
          <version>2.0.1</version>
      </dependency>
      <dependency>
          <groupId>com.google.code.guice</groupId>
          <artifactId>guice-struts</artifactId>
          <version>2.0.1</version>
      </dependency>
      <dependency>
          <groupId>com.google.code.guice</groupId>
          <artifactId>guice-servlet</artifactId>
          <version>2.0.1</version>
      </dependency>
      <dependency>
          <groupId>com.jteigen.scalatest</groupId>
          <artifactId>junit4runner</artifactId>
          <version>1.0</version>
          <scope>test</scope>
      </dependency>

  其中ScalaTest似乎一款針對Guice的JUnit的Runner,這有待研究。
arrow
arrow
    全站熱搜

    Jemmy 發表在 痞客邦 留言(0) 人氣()