いくつかのオプションを考えることができます。
(1) リスナーを通常どおり (web.xml に) 登録し、サーブレット コンテキスト属性からインジェクターを取得します。 GuiceServletContextListener
の属性名で初期化した後、インジェクターインスタンスをサーブレットコンテキストに入れますInjector.class.getName()
。これが文書化またはサポートされているかどうかはわかりません。そのため、インジェクターに独自の属性名を定義して、自分で配置することをお勧めします。リスナーの初期化順序を考慮してください。GuiceServletContextListener が呼び出されるまで、インジェクターはバインドされません。
class MyListenerExample implement HttpSessionListener { // or whatever listener
static final String INJECTOR_NAME = Injector.class.getName();
public void sessionCreated(HttpSessionEvent se) {
ServletContext sc = se.getSession().getServletContext();
Injector injector = (Injector)sc.getAttribute(INJECTOR_NAME);
// ...
}
}
(2) Java Servlets API バージョン 3.0 以降を使用している場合はaddListener
、ServletContext を呼び出すことができます。どこでも実行できますが、インジェクタを作成するときに正しく実行することをお勧めします。このアプローチは私には少しハックに感じますが、うまくいくはずです。
public class MyServletConfig extends GuiceServletContextListener {
ServletContext servletContext;
@Override
public void contextInitialized(ServletContextEvent event) {
servletContext = event.getServletContext();
// the super call here is where Guice Servlets calls
// getInjector (below), binds the ServletContext to the
// injector and stores the injector in the ServletContext.
super.contextInitialized(event);
}
@Override
protected Injector getInjector() {
Injector injector = Guice.createInjector(new MyServletModule());
// injector.getInstance(ServletContext.class) <-- won't work yet!
// BIND HERE, but note the ServletContext will not be in the injector
servletContext.addListener(injector.getInstance(MyListener.class));
// (or alternatively, store the injector as a member field and
// bind in contextInitialized above, after the super call)
return injector;
}
}
上記のすべての組み合わせで、リスナーが GuiceFilter パイプライン内で呼び出されるとは限らないことに注意してください。したがって、特に、うまくいくかもしれませんが、リスナーで HttpServletRequest や HttpServletResponse などの Request スコープのオブジェクトへのアクセスに依存しないことをお勧めします。