Click と Guice を連携させる。

 Click Framework が最近お気に入りです。それで、Seasar 党の私ではありますが、Guice のシンプルさも気になっている今日この頃なのです。

 ということで、Click Framework の Page クラスに Guice でインジェクションを施したいんだけどどうしたらいんだろう? ということになりました。それで S2Click のソースなどをそぞろ見ていたのですが、ぜんぜん見当違い(というか私のやりたいことと微妙にずれている)でした。

 ということで、自分なりに考えてみたやり方。とても簡単です。まず前準備として、guice-1.0.jar に加えて guice-servliet-1.0.jar もデプロイします。次に ClickServlet を継承して Guice によるインジェクションを行うサーブレットを作成します。↓こんな感じです。

package example;

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

import net.sf.click.ClickServlet;
import net.sf.click.Page;

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

public class GuiceClickServlet extends ClickServlet {
    private Injector injector;

    @Override
    public void init() throws ServletException {
        super.init();

        injector = Guice.createInjector(new AbstractModule() {
            @Override
            protected void configure() {
                // ↓これがミソ
                install(new ServletModule());

                // ここにインジェクションの設定を書く
            }
        });
    }

    @Override
    protected Page newPageInstance(String path, Class pageClass,
        HttpServletRequest request) throws Exception {

        return (Page) injector.getInstance((Class<?>) pageClass);
    }
}

web.xml を編集して、ClickServlet のかわりにこの↑クラスを使用するように変更します。また、Guice のフィルタも定義します。web.xml は↓こんな感じになります。

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
    <display-name>Example</display-name>
    <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>
    <servlet>
        <servlet-name>click-servlet</servlet-name>
        <servlet-class>example.GuiceClickServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>click-servlet</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.htm</welcome-file>
    </welcome-file-list>
</web-app>

以上です。S2Click はパスとクラスの結びつけは dicon に記述して Seasar が行いますが、これは Click がもともともっているパスとクラスの結びつけ機構をそのまま利用します。なので、Page クラス自体を Guice に登録する必要はありません。