2009-04-23 14 views
6

内のスレッド私は春を使用してWebアプリケーションを持っているし、休止状態と支柱(これはTomcatで動作します)

呼び出しシーケンスは、このようなものです...

Strutsアクションは、今度は春のサービスBeanを呼び出しますSpring DAO Beanを呼び出します。 DAO実装はHibernateの実装です。

質問があります 私の春の豆はすべて同じ糸で動いていますか? ThreadLocalに何かを保存し、それを別のBeanに入れることはできますか?

私はこれがStateless Session Beanではうまくいかないと確信しています。 EJBコンテナは、セッションBeanへの呼び出しごとに新しいスレッドを生成することができます(または作成します)

スプリングコンテナは同じですか?すなわち、同じスレッド内のすべてのBeanを実行しますか? 。私はテストケースとアクション

で唯一のスレッドがあったと信じて私をリード2 beans-中にThread.currentThread()のgetId()を介して同じIDを持って - 私は、JUnitテストを試してみました

または動作が予測できませんか? Tomcatサーバーで実行しているときに変更されますか?

明確化 2つのスレッド間でデータを交換したくありません。私は、ThreadLocalにデータを入れ、コールスタック内のすべてのBeanからデータを取得できるようにします。これは、すべてのBeanが同じスレッド内にある場合にのみ機能します。

+0

サンプルコードを投稿してください。私はそれがあなたが達成しようとしていることは分かりません。 –

答えて

15

Springはスレッドを生成しません。 Tomcatはそうです。 Springはオブジェクトを作成して配線するだけです。

ブラウザからの各リクエストは1回のリクエストで処理されます。要求を処理するのはTomcatです。要求を処理するスレッドを作成するのはTomcatです。

"X"という名前のSpringでシングルトンBeanを作成したばあいです。そして、Xの同じインスタンスがすべての要求によって使用されます。

Spring Beanはスレッドには存在しません。それらはヒープ上に割り当てられたばかりです。

+0

Tomcatの下で実行しているとき、エンドツーエンドのフローは1つのスレッドの下にありますか? –

+0

はい、すべてが同じアプリケーションサーバーインスタンスにあると仮定します。 –

+0

これはこれまでのところ最良の説明です。 –

1

私の春の豆はすべて同じスレッドで を実行しますか?私は をThreadLocalに保存して、別のBeanに を得ることができますか?あなたが言及したコンポーネント(サービスBean、DAO bean - 私はそれらがプレーンスプリングビーンだと思います)のためのAFAIKは、新しいスレッドを生成しません。私はあなたのユースケース(すなわち、2つのスレッド間でデータを交換する)を理解していません。

は、ほとんどのWebアプリケーションの場合は、新しいスレッドがそれぞれの新しい要求のために生み出された、とされる次の2つの要求の間でデータを共有したい場合、通常: - セッションを使用 - データ を渡すためにGET/POSTパラメータを使用しますデータを共有する

あなたの質問に答えるために、私はスプリングコンテナがほとんどのコンポーネントのスレッドを生成しないと確信しています。

+0

私は2つのスレッド間でデータを交換したくありません。私はスレッドにデータを入れ、呼び出しスタックのすべてのBeanからデータを取得できるようにしたい。これは、すべてのBeanが同じスレッド内にある場合にのみ機能します... –

0

はい、これを行うことができます。同じスレッドがあなたのアクションを実行するために使用され、ThreadLocalが機能します。通常、ステートレスセッションBeanに対しても同じスレッドが使用されます。ステートレスセッションBeanは、同じアプリケーションサーバーインスタンスで実行されているものとします。おそらくベンダーに依存しているので、これには依存しません。

このテクニックを使用して、コード内の任意の場所で発信者IDにアクセスします。セッションBeanとJMSも使用しますが、明示的にコンテナ間で情報を渡し、各エントリポイントでThreadLocalを設定します。この方法では、Bean(セッションまたはmdb)がローカルかどうかは関係ありません。

+0

私は彼が実際にはステートレスセッションBeanを使用しているとは思わなかったのですか?私は代わりにSpringでPOJOを使用していると推測していました。 –

+0

デフォルトでは、SpringはBeanをシングルトンとして作成します。つまり、同じインスタンスがすべてのリクエストで共有されます。しかし、もし彼がThreadLocalに何かを保存するなら、それは問題ではありません。 –

+0

私はあなたのPOJOの点について正しいと思っていますが、彼はそれがうまくいくとは思っていないと言いましたので、これが(Springの有無にかかわらず)考えていた別の選択肢かもしれないと思います。私はちょうど、私にも同様のことをしている私自身の経験に基づいて、彼にそれに関するいくつかの情報を与えるだろうと思った。 – Robin

0

すべての他の回答に加えて、私は次のように追加します。

通常のスレッドを切り替える唯一の理由はparallellityのためのいくつかの要件です。これは通常、複雑さの点では無料ではないので、通常、これが発生したときにはっきりと通知されます。

要求のシングルスレッド処理のように見えるスレッド内のスレッドを切り替えることは、実際には非常に複雑です。これは通常、コンテナ内の1か所でのみ発生し、これは通常、外部クライアントから要求を受け取るtcp/ipソケットリーダーによって処理されます。これらのリーダースレッドは、通常、どのスレッド(プール)が要求を処理し、そのスレッドに要求を転送するかを決定します。その後、リクエストはそのスレッドにとどまります。

通常、発生する可能性のある唯一のことは、並列性または非同期処理(JMSなど)用に追加のスレッドが作成されることです。