1

Web サービスでキャッシュを作成しようとしています。このために、このキャッシュを他のステートレス Bean に提供するために、新しいステートレス Bean を作成しました。このキャッシュは、MyObject が POJO である単純な静的 ConcurrentMap です。問題は、異なるキャッシュ オブジェクトがあるように見えることです。1 つはクライアント Bean 用で、もう 1 つはローカルです。

-CacheService
-CacheServiceBean
  -getMyObject()
  -insertMyObject(MyObject)
  -size()

-SomeOtherBean
 cache = jndiLookup(CacheService)
 cache.insertMyObject(x)
 cache.size() -> 1

この割り当ての後、CacheServiceBean 内から cache.size を呼び出すと、0 になります。Bean を介して静的シングルトンを共有することは可能ですか? 最終的にデータベーステーブルを使うことにしましたが、まだ考え中です。

ご回答ありがとうございます。

4

5 に答える 5

4

私が覚えている限りでは、ステートレス Bean が静的フィールドにデータを保持するのに十分なほどグローバルであると確信することはできません。これに役立ついくつかのキャッシング フレームワークが存在します。多分memcache

編集: http://java.sun.com/blueprints/qanda/ejb_tier/restrictions.html#static_fields言います:

非 final 静的クラス フィールドは、EJB では許可されません。そのようなフィールドがあると、エンタープライズ Bean の配布が困難または不可能になるからです。

于 2009-01-30T22:49:44.233 に答える
3

一見すると、これは矛盾しているように見えます。キャッシュは、少なくとも一般的な意味では、ほぼ確実にステートレスとは見なされないものだからです。

于 2009-01-30T23:39:04.897 に答える
2
@Stateless
public class CacheSessionBean implements CacheSessionLocal {
    private static Map<String, Object> cacheMap = new HashMap<String, Object>();

    public Object getCache(String key) {
        return cacheMap.get(key);
    }

    public void putCache(String key, Object o) {
        cacheMap.put(key, o);
    }
}

クラスタ内の EJB の分散に関する警告は、静的変数に適用されます。ただし、クラスタリングを行っていない場合、それらはほとんど当てはまらないため、このレベルでは静的は「大丈夫」です。

同期の問題が発生します。

これを軽減する 1 つの方法は、コンテナーを構成して CacheSession Bean の 1 つのインスタンスのみを作成およびプールすることです。そうすれば、コンテナーがその同期を管理します。

自分で同期を管理することもできますが、EJB メソッド レベルでそれを行うべきではありません。むしろ、同期された Cache オブジェクト (一般的な HashMap に対して) を使用する方がよいでしょう。

しかし、この時点で重要なことは、静的変数は単に静的変数であるということです。

理論的には、Session Bean のコンテナーのライフサイクルを認識する必要があります (すべてのインスタンスを解放する可能性があり、それによって実際の Bean クラスが GC の対象となり、静的データが失われる可能性があるため)。ただし、実際には、サービスが人気がある場合、これは起こりそうにありません。しかし、参考までに、それは起こる可能性があります。

于 2009-01-30T23:33:40.213 に答える
1

ステートレス Bean を使用する場合、それらのインスタンスの数を制御することはできません (これはアプリ サーバーが処理します)。クライアントから検索したものとは別の Bean から出力を取得できた可能性があります。ログにそれを印刷しましたか?その場合、おそらく複数の出力が表示されているはずです。要点は、jndi を介してステートレス Bean をルックアップするときに、どのインスタンスを取得するかを知ることができないということです (取得するのは 1 つだけです)。また、状態がないため、これがキャッシュに最適かどうかはわかりません。

静的シングルトンとは、シングルトンオブジェクトを意味すると思いますか? はい、多くの Bean を介してシングルトンにアクセスすることは問題になりません。ただし、おそらく発生する同時実行の問題を覚えておいてください。アプリ サーバー (一般的には Bean) は、多くのことを抽象化します。

于 2009-01-30T22:51:02.343 に答える
1

この投稿が少し前のものであることは知っていますが、元の質問が目指していたキャッシュのニーズを満たす新しいシングルトン Bean があるようです。

http://download.oracle.com/javaee/6/tutorial/doc/gipjg.html

シングルトン セッション Bean はステートレス セッション Bean と同様の機能を提供しますが、アプリケーションごとにシングルトン セッション Bean が 1 つしかないという点で異なります。ステートレス セッション Bean のプールとは対照的に、いずれかがクライアント要求に応答する可能性があります。ステートレス セッション Bean と同様に、シングルトン セッション Bean は Web サービス エンドポイントを実装できます。

私はそれを作成して、WebService/Stateless Bean からの問題を参照しようとしました。宣伝どおりに機能しました。

于 2011-08-09T23:41:18.677 に答える