16

私はJSF+Facelets Webアプリを構築しています。その一部は、ディレクトリを頻繁にスキャンし、変更にインデックスを付けるメソッドです。このメソッドは、アプリケーションスコープに含まれるBeanの一部です。Xミリ秒ごとにメソッドを呼び出すTimerTaskのサブクラスを作成しました。私の問題は、Beanを初期化することです。ページ上のBeanを参照できます。ページに移動すると、Beanが初期化され、指示どおりに機能します。代わりに、Webコンテキストが初期化されるときにBeanが初期化されるようにしたいので、インデックス作成メソッドを開始するためにページにアクセスする必要はありません。Googleはこの機能を望んでいる人を何人か示しましたが、Springとの統合以外に実際の解決策はありません。これは、この機能を取得するためだけに実行したくないものです。

「load-on-startup」が設定されているサーブレットとServletContextListenerの両方を試してみましたが、FacesContextがないため、正しく設定できませんでした。利用可能、またはJSF環境からBeanを参照できないため。

Webアプリの起動時にJSFBeanを初期化する方法はありますか?

4

3 に答える 3

15

コードがFacesContextを呼び出す場合、JSF リクエスト ライフサイクルに関連付けられたスレッドの外では機能しません。リクエストごとに FacesContext オブジェクトが作成され、リクエストの最後に破棄されます。静的呼び出しを介してフェッチできる理由は、リクエストの開始時にThreadLocalに設定されているためです。FacesContext のライフサイクルは、ServletContext のライフサイクルとは関係ありません。

これでは不十分かもしれませんが (すでにこのルートをたどっているように聞こえます)、ServletContextListener を使用して、必要なことを実行できるはずです。FacesContext へのすべての呼び出しが JSP の要求スレッドに保持されていることを確認してください。

web.xml:

<listener>
    <listener-class>appobj.MyApplicationContextListener</listener-class>
</listener>

実装:

public class MyApplicationContextListener implements ServletContextListener {

    private static final String FOO = "foo";

    public void contextInitialized(ServletContextEvent event) {
        MyObject myObject = new MyObject();
        event.getServletContext().setAttribute(FOO, myObject);
    }

    public void contextDestroyed(ServletContextEvent event) {
        MyObject myObject = (MyObject) event.getServletContext().getAttribute(
                FOO);
        try {
            event.getServletContext().removeAttribute(FOO);
        } finally {
            myObject.dispose();
        }
    }

}

このオブジェクトは、JSF アプリケーション スコープを介して (または、同じ名前の変数が他に存在しない場合は直接) アドレス指定できます。

<f:view>
    <h:outputText value="#{applicationScope.foo.value}" />
    <h:outputText value="#{foo.value}" />
</f:view>

JSF マネージド Bean でオブジェクトを取得する場合は、ExternalContextから取得できます。

FacesContext.getCurrentInstance()
            .getExternalContext().getApplicationMap().get("foo");
于 2008-11-27T00:29:30.493 に答える
0

JSF 2+では、を使用しSystemEventListenerて処理できます。初期化するためにアクションを実行するようPostConstructApplicationEventに設定します。

<system-event-listener>
    <system-event-listener-class>
     listeners.SystemEventListenerImpl
    </system-event-listener-class>
    <system-event-class>
     javax.faces.event.PostConstructApplicationEvent
    </system-event-class>                       
</system-event-listener>

実装は次のようになります。

public class SystemEventListenerImpl implements SystemEventListener {

  @Override
  public void processEvent(SystemEvent event) throws AbortProcessingException {
    Application application = (Application) event.getSource();
   //TODO
  }

  @Override
  public boolean isListenerForSource(Object source) {
    return (source instanceof Application);
  }
}

これにより、単に値を渡すだけでなく、多くのことができるようになります。

于 2012-07-13T19:10:10.977 に答える
0

Using listeners or load-on-startup, try this: http://www.thoughtsabout.net/blog/archives/000033.html

于 2008-11-24T19:35:40.710 に答える