続・Wicket + Guice + warp-persist + JPA を試す

 先日のエントリのやり方では Tomcat 上では動いても Glassfish では動かないことがわかりましたので、訂正します。

 インジェクタの初期化を Wicket つまり、フィルタ(Wicket はフィルタとして動作している)で行ってはいけないようなので、リスナで初期化を行います。

package com.example.listener;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.servlet.GuiceServletContextListener;
import com.wideplay.warp.persist.PersistenceService;
import com.wideplay.warp.persist.UnitOfWork;
import com.wideplay.warp.persist.jpa.JpaUnit;

public class MyServletContextListener extends GuiceServletContextListener {

    @Override
    protected Injector getInjector() {
        // warp-persist の Guice モジュール生成
        Module warpModule = PersistenceService.usingJpa().across(UnitOfWork.REQUEST).buildModule();

        // Guice Injector を生成
        return Guice.createInjector(warpModule, buildWebModule());
    }

    private Module buildWebModule() {
        return new AbstractModule() {
            @Override
            public void configure() {
                // JPA の persistence.xml に記述している persistence-unit name を指定
                bindConstant().annotatedWith(JpaUnit.class).to("persistence-unit name");
            }
        };
    }
}

web.xml にリスナを追加します。

    <listener>
        <listener-class>com.example.listener.MyServletContextListener</listener-class>
    </listener>

WicketApplication クラスの init メソッドは以下のようにします。

    @Override
    protected void init() {
        super.init();

        // サーブレットコンテキストからインジェクタを取得
        Injector injector = (Injector) getServletContext().getAttribute("com.google.inject.Injector");

        // Wicket にインジェクタを登録
        addComponentInstantiationListener(new GuiceComponentInjector(this, injector));
    }