2
@WebListener
public class AllRequestsWebListener implements ServletRequestListener {

    @Inject HttpRequestProducer producer;

    public void requestInitialized(ServletRequestEvent sre) {
    producer.requestInitialized(sre);
    }
}

...

@RequestScoped
public class HttpRequestProducer {
...
}

request-bean を method-parameter として注入する方法がわからないので、Request-bean の注入が threadLocal の場合に適切に機能すると推測できます。スレッドセーフな方法で実装する方法を説明してもらえますか?

4

2 に答える 2

1

Bean に注入したのは、実際の取引を表すプロキシです。プロキシは常に呼び出しを正しい Bean に転送します

于 2013-06-25T09:12:46.693 に答える
0

直感に基づく答え

リクエストスコープはスレッドセーフであるため、スレッドセーフであると思います(ユーザーは複数のブラウザーセッションを開いて同じセッションIDを使用できるため、セッション以上はそうではありません)

経験的な証拠ですが、私はそれをテストしましたが、注入されたものHttpRequestProducerはリクエストごとに新しいインスタンスを取得します。

requestInitializedと は異なるスレッドになる可能性がある (そして実際には異なるスレッドである)ことに注意してくださいrequestDestroyed。したがって、両方のメソッドで同じ注入されたオブジェクトを使用する場合は、さらに調査します。

仕様に裏付けられた回答

困難な部分は、仕様でこの主張の確固たる証拠を見つけることでした.

CDI 仕様を調べたところ、@RequestScoped オブジェクトがスレッド セーフであるという決定的な証拠をすぐに見つけることができませんでした (たとえば、スレッド ローカルを使用)。 (こちらをご覧ください

そこで興味深いのが次の句です。

共有リソースへの同時アクセスの制御 マルチスレッド サーバーでは、共有リソースに同時にアクセスできます。スコープ オブジェクトの属性に加えて、共有リソースには、メモリ内データ (インスタンス変数やクラス変数など) と、ファイル、データベース接続、ネットワーク接続などの外部オブジェクトが含まれます。

同時アクセスは、いくつかの状況で発生する可能性があります。

  • Web コンテキストに格納されているオブジェクトにアクセスする複数の Web コンポーネント。

  • セッションに格納されたオブジェクトにアクセスする複数の Web コンポーネント。

  • インスタンス変数にアクセスする Web コンポーネント内の複数のスレッド。Web コンテナは通常、各リクエストを処理するスレッドを作成します。サーブレット インスタンスが一度に 1 つの要求のみを処理するようにしたい場合、サーブレットは SingleThreadModel インターフェイスを実装できます。サーブレットがこのインターフェースを実装する場合、サーブレットのサービス メソッドで 2 つのスレッドが同時に実行されないことが保証されます。Web コンテナは、サーブレットの 1 つのインスタンスへのアクセスを同期するか、Web コンポーネント インスタンスのプールを維持し、それぞれの新しい要求をフリー インスタンスにディスパッチすることによって、この保証を実装できます。このインターフェースは、Web コンポーネントが静的クラス変数や外部オブジェクトなどの共有リソースにアクセスすることに起因する同期の問題を防止しません。さらに、Servlet 2.

したがって、理論的には、オブジェクト自体はリクエスト スレッドごとに 1 つのインスタンスを持つように見えますが、これがサポートされているという確固たる証拠は見つかりませんでした。

于 2013-06-25T15:49:18.597 に答える