1

@StatefulEJB(3.x)では、Session Beans:および。を選択できます@Stateless。これらの2つのオプションの背後にある基本を理解している場合:

  • @Stateful-各ユーザー/クライアントは独自のものを取得するため、通常はプールされません。複数のリクエストにわたって状態を維持します
  • @Stateless-リクエスト間の状態を維持しないため、通常はプールされるため、新しいクライアントリクエストごとに新しいBeanが取得されます

ここでの私の中心的な質問は非常に単純ですが、それに接するいくつかのミニ質問があります。私のPOJOデザインはBeanとBeanでどのように異なりますか?@Stateful@Statelessつまり、インターフェイスHelloWorldを実装するBeanがある場合Hello、そのPOJOのデザインは、ステートフルにするかどうかによってどのように変化しますか?

これに接する:

  • アプリコンテナ(私の場合はGlassFish)は、ステートフルであるかどうかに応じて、EJBにどのような異なる制限を課しますか?
  • の場合@Stateful、同じユーザー/クライアントからのクライアント側のリクエストは、どのようにして正しいBean(前のリクエストからのクライアントの状態を維持しているBean)にマップされますか?
  • セッションBeanはいつ死にますか?のリクエストが行われた直後だと思います@Statelessが、の手がかりはありません@Stateful

ここで明確にしてくれてありがとう。

4

4 に答える 4

2

コア質問「私のPOJOデザインは@StatefulBeanと@Statelessでどのように異なりますか」について:

hello worldの例は、@ StatelessセッションBeanの優れた例です。実装には状態がありません(クラスインスタンス変数はありません)。状態については何も仮定していません。@Stateless Beanで「詳細情報」が必要な場合は、それを調べたり、(再)計算したりします。このルールを破り、Beanでインスタンス変数を定義した場合、情報が期待どおりになるという保証はありません。 Beanを呼び出すたびに実行されます。実行しないでください。

@Stateful Beanの設計では、コンテナーがBeanの存続期間中保持する内部状態(クラスインスタンス変数)を保持します。Beanはシリアル化可能である必要があります。セッションの存続期間中Beanを維持することに関連して、非常に現実的な実行時コスト(メモリ、および2番目の接線方向の質問に関する問題の管理)があります-したがって、これは適切な場合にのみ使用してください(これは正当化されます@Stateless Beansの存在)。

たとえば、単純なサインアップページについて考えてみます。ユーザー名、電子メールアドレスなどを入力し、その後に「よろしいですか」と入力します。@Stateful Beanは、バックエンドに送信する準備ができるまで、この一時情報を保持できます。

例としてGoogle; これが1つです:http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/6/html/Beta_Documentation/Stateful_Session_Bean_Example.html

クライアント側が正しい@StatefulBeanにマップされる方法は、実際には実装に依存します(指定されていません)が、サーブレットセッション情報が維持される方法と同様に管理されることが期待できます。とはいえ、サーブレットセッションを@Statefulセッションと混同しないでください。これらはまったく同じものではありません。

@StatefulBeanのJavaEE5/6の場合、1つのメソッドに@Removeの注釈を付け、クライアントがそのメソッドを呼び出すと、エーテルに解放されます。それ以外では、@ステートフルBeanへの参照を保持している限り(つまり、サーブレットセッションで)、必要なときに@ステートフルBeanが存在することを期待できます。

参照:http ://docs.oracle.com/javaee/5/tutorial/doc/bnbmt.html

于 2012-07-06T20:24:58.430 に答える
0

1)EJB/Pojoは実際には違いを認識していません。開発者としてのあなたはそうしますが、コードレベルでは、ステートレスBeanはステートフルBeanとほとんど同じように見えます。ライフサイクルとコールバックは事実上同じです。違いは、クライアントがそのライフサイクルをより詳細に制御できるのに対し、ステートレスBeanではコンテナがそのライフサイクルを制御できることです。

2)クライアントは単にSessionBeanインスタンスのコピーを維持します。したがって、たとえば、Webコンテナでは、インスタンスをセッションに単純に詰め込むことができます。やりたくないのは、リクエストごとにステートフルセッションBean(@EJBを使用)を継続的に注入することです。これにより、毎回新しいものが作成されます。セッションが存在しない場合は、セッションを確認してから、通常どおりに検索することをお勧めします。

3)ステートフルBeanは、@Removeで注​​釈が付けられたメソッドを持つことができます。このメソッドを呼び出すと、Beanは破棄されます。このメソッドを呼び出さない場合、コンテナにはタイムアウト機能があり、設定された期間の後にセッションBeanを自動的に取得します。ステートフルBeanがサーバーの再起動を生き残ることは期待できません(ただし、そのコントラクトはクラスター環境では異なる場合があります)。

また、ほとんどが機能するレガシーEJB 2の動作もたくさんあります。それに到達するには、フープをジャンプするだけです。最新のものの方が簡単です。

于 2012-07-06T19:26:12.830 に答える
0
  • ステートレスセッションBeanにインスタンス変数がある場合、それらの値は無意味になります(実際には)。これは、リクエストを処理するためにステートレスセッションBeanのどのインスタンスがインスタンスプールから取得されるかがわからないためです。

  • ステートレスセッションBeanは、コンテナがそれらを強制終了することを決定した場合にのみ死にます。それらは必要に応じてインスタンス化され、コンテナがそれらを破棄することを決定した場合にのみ破棄されます(たとえば、インスタンスプールを小さくすることを決定した場合)。あなたはそれらが要求の後に破壊されるとあなたが仮定すると言います、しかしこれは正しくありません。リクエスト後、それらはインスタンスプールに戻され、次のリクエストを処理する準備ができたままになります。

于 2012-07-06T20:00:32.557 に答える
0

質問が多いので、すぐに答えて、追加情報へのリンクを提供しようと思います。

アプリコンテナ(私の場合はGlassFish)は、ステートフルであるかどうかに応じて、EJBにどのような異なる制限を課しますか?

あなたの場合の主な違いは、仕様からの次の引用でわかります:

ステートレスセッションBeanは、インスタンスに会話状態がないセッションBeanです。これは、クライアントによって呼び出されたメソッドのサービスに関与していない場合、すべてのBeanインスタンスが同等であることを意味します。「ステートレス」という用語は、インスタンスに特定のクライアントの状態がないことを意味します。ただし、インスタンスのインスタンス変数には、クライアントによって呼び出されたメソッド呼び出し全体の状態を含めることができます。このような状態の例には、開いているデータベース接続やエンタープライズBeanオブジェクトへのオブジェクト参照が含まれます。

@Statefulの場合、同じユーザー/クライアントからのクライアント側のリクエストは、どのようにして正しいBean(前のリクエストからのクライアントの状態を維持しているBean)にマップされますか?

クライアント側では、ステートフルセッションBeanのビジネスインターフェイスへの参照を保存する必要があります。EJBコンテナから取得したこのオブジェクト。これは、サーバー側オブジェクトの検索方法に関する詳細を含むコンテナー作成オブジェクトです。GlassFishのこれらのプロキシに関するいくつかの情報は、次の場所から見つけることができます。

セッションBeanはいつ死にますか?@Statelessのリクエストが行われた直後だと思いますが、@Statefulの手がかりはありません。

いいえ、ステートレスセッションBean(SLSB)は要求後に停止しません。ステートレスセッションBeanの寿命は次のとおりです。

  1. コンテナがそのように決定したときに作成されます。これは、使用される前のある時点で自然に発生しますが、それ以外の場合はコンテナの手に渡ります。SLSBが作成されると、プールに配置されます。
  2. 一部のクライアントがSLSBでメソッドを呼び出す必要がある場合、メソッド呼び出しの期間中、1つのインスタンスがプールから削除されます。メソッド呼び出しが終了すると、インスタンスはプールに戻されます。これで、このインスタンス(他のインスタンス)は次のクライアントにサービスを提供する準備が整います。
  3. コンテナがプールのサイズを調整することを決定すると、SLSBの寿命は終了します

ステートフルセッションBean(SFSB)の寿命は、おおまかに次のとおりです。

  1. JNDIルックアップまたはインジェクションが発生すると、コンテナーによって新しいインスタンスが作成されます。
  2. SFSBは、その存続期間中、複数のメソッド呼び出しを処理できます。また、不動態化(基本的にはリソースを節約するためにディスクに保存)して、再度アクティブ化することもできます。
  3. 削除メソッドが呼び出されるか、タイムアウト(SFSBが一定期間使用されていなかった)が発生すると、SFSBの有効期間は終了します。コンテナには通常、実装固有のデフォルトのタイムアウトがあり、タイムアウトも調整できます。Java EE 6(EJB 3.1)では、このタイムアウトはStatefulTimeoutを介してBeanごとに調整できます。

さらに、システム例外が発生すると、セッションBeanのインスタンスは破棄されます。システム例外は、RuntimeException(アプリケーション例外としてマークされていない)またはjava.rmi.RemoteExceptionです。SLSBのインスタンスが破棄されるという事実は、クライアントに対して透過的です。次の呼び出しは、SLSBの他のインスタンスによって確実に処理されます。SFSBの場合、SFSBのサーバー側インスタンスが存在しないため、将来発生する可能性のあるすべてのビジネスメソッド呼び出しは失敗します。詳細については、EJB3.1仕様の第14章を参照してください。

ライフサイクルの明確で詳細な説明は、EJB 3.1仕様(4.6、4.7)に記載されています。上記よりも詳細でグラフ付きの説明は、JavaEE6チュートリアルにあります。

そして、Helloサービスの設計の主な効果は何ですか?

@Stateless
public class HelloStateless implements HelloRemote {
    @Override
    public String getGreeting(String name) {
        return "Hi " + name;
    }
}


/**
 * This design is not possible for Stateless, because
 * subsequent calls to setName and getGreeting can be
 * handled by two different instances. For stateful it 
 * is fine, because we use one exclusively one instance.
 */
@Stateful
public class HelloStateful {

    private String name;
    public void setName(String name) {
        this.name = name;
    }

    public String getGreeting() {
        return "Hi " + name;
    }
}
于 2012-07-10T07:02:59.920 に答える