PR

Webアプリケーションでの利用

 WebアプリケーションでGuiceを利用するために,com.google.inject.servlet.GuiceFilterが用意されています。これは,javax.servlet.Filterを実装して作成されたフィルタなので,以下のようにweb.xmlに定義することで使用可能です。また,Webアプリケーションで使用する場合guice-servlet-1.0.jarをクラスパスに含める必要があります。


<filter>
  <filter-name>Guice Servlet Filter</filter-name>
  <filter-class>
    com.google.inject.servlet.GuiceFilter
  </filter-class>
</filter>
<filter-mapping>
  <filter-name>Guice Servlet Filter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
リスト20●フィルタの定義(web.xml)

 フィルタがかかっている状態で,com.google.inject.servlet.ServletModuleを使用してインジェクタを作成することで,リスト21のようにリクエストを取得することができます。

 CreateInjectorメソッドは,可変長引数を取ることが可能なので,他にインジェクションをする場合は,必要な数だけ引数として渡せば実行可能です。


Injector injector =
  Guice.createInjector(new ServletModule());
HttpServletRequest request = 
  injector.getInstance(HttpServletRequest.class);
リスト21●Guiceでのリクエストの取得

 また,リスト22のように@RequestParametersを使用すると,Map<String, String[]>にリクエストとして送信されたパラメータが設定されます。これにより業務クラスがServletに依存しなくなり,POJOとして作成しやすくなります。リスト23のように,このクラスをサーブレット内でインジェクタから取得することで利用できます。


package jp.co.nikkeibp.itpro.guice.web;
import java.util.Map;
import com.google.inject.Inject;
import com.google.inject.servlet.RequestParameters;
public class Logic {
    @Inject
    @RequestParameters
    private Map<String, String[]> params = null;
    public String execute() {
    // paramsを使用して業務ロジックを記述する
    return params.get("name")[0];
    }
}
リスト22●@RequestParametersを使用したパラメータの取得


package jp.co.nikkeibp.itpro.guice.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.servlet.ServletModule;

public class TestServlet extends HttpServlet {

  protected void doGet(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException {
  Injector injector = Guice.createInjector(new ServletModule());
  Logic logic = injector.getInstance(Logic.class);
  request.setAttribute("name", logic.execute());
  }
  protected void doPost(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException {
  Injector injector = Guice.createInjector(new ServletModule());
  Logic logic = injector.getInstance(Logic.class);
  request.setAttribute("name", logic.execute());
  }
}
リスト23●サーブレット内での取得方法

Spring Frameworkと連携してみよう

 Guiceは,上記のように単独で使用するのはもちろんのこと,Springと連携することも可能です。SpringのコンテナにあるBeanをGuiceで管理し,オブジェクトの取得やインジェクションが可能になります。

 連携するには,モジュールでcom.google.inject.spring.SpringIntegration#fromSpringメソッドを使用します。これによりSpringのDIコンテナで管理されているbeanをGuiceでも使用できるようになります。

 ここで連携に使用したSpringのバージョンは2.0.4です。またGuiceのサイトにあるguice-spring-1.0.jarをクラスパスに含める必要があります。


package jp.co.nikkeibp.itpro.guice.spring;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import com.google.inject.AbstractModule;
import com.google.inject.spring.SpringIntegration;
public class Module extends AbstractModule {
    ApplicationContext context = null;
    public Module(ApplicationContext context){
    this.context = context;
    }
    @Override
    protected void configure() {
    bind(BeanFactory.class).toInstance(context);
    bind(Client.class).toProvider(
        SpringIntegration.fromSpring(Client.class, "client"));
    }
}
リスト24●Springと連携する場合のモジュール

 Springのbean定義ファイルにbean同士の依存関係を記述します。連携を行う場合でも,Springのbean定義ファイルは普通に使用するのと変わりません。


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xsi:schemaLocation=
  "http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
  <bean id="client" class="jp.co.nikkeibp.itpro.guice.spring.Client">
  <constructor-arg index="0">
    <ref local="hello" />
  </constructor-arg>
  </bean>

  <bean id="hello"
    class="jp.co.nikkeibp.itpro.guice.spring.HelloServiceImpl">
  </bean>
</beans>
リスト25●Spring定義ファイル(applicationContext.xml)

 Springを使用して,先ほど作成したapplicationContext.xmlを読み取ってDIコンテナを作成し,それをモジュールに設定してGuiceに渡します。


package jp.co.nikkeibp.itpro.guice.spring;
import org.springframework.context.ApplicationContext;
import
  org.springframework.context.support.ClassPathXmlApplicationContext;
import com.google.inject.Guice;
import com.google.inject.Injector;
public class Main {
    public static void main(String[] args) {
    ApplicationContext context
    = new ClassPathXmlApplicationContext(
      "/jp/co/nikkeibp/itpro/guice/spring/applicationContext.xml");
    Module module = new Module(context);
    Injector injector = Guice.createInjector(module);
    Client client = injector.getInstance(Client.class);
    client.execute();
    }
}
リスト26●Springのコンテキストを作成し,それをGuiceから取得するメインクラス

 以上のようにすることで,Springで定義していたbeanもGuiceに渡して連携することが可能になります。すでにSpringで作成したbeanがあってGuiceに移行する場合には,現行を活かしつつGuiceを使用することができます。