web-dev-qa-db-ja.com

EJBとは何ですか?

EJB Beanが何であるかを学習しようとしています。それは、インスタンスがプールで管理されているという意味です。本当にそれらの良いグリップを得ることができません。

それらが実際に何であるか説明できますか(Javaプログラマーにとって)?彼らは何をしますか?彼らの目的はどれですか? なぜ実際にそれらを使用するのですか? (なぜPOJOに固執しないのですか?)おそらくアプリケーションの例でしょうか?

更新された情報、つまりEJB 3.1のみを参照してください。 EJBに関する日付情報は誤解を招く可能性があります。

EJBを学習する初心者の場合は、次のことに注意してください。

EJBは分散オブジェクトに基づいており、これはnetworkでリンクされた複数のマシン(仮想または物理)で実行されているソフトウェアを指します。

144
jacktrades

なぜ実際にそれらを使用するのですか?(POJOに固執しないのはなぜですか?)

データベースにアクセスするコンポーネント、他の接続/ディレクトリリソースにアクセスするコンポーネント、または複数のクライアントからアクセスするコンポーネント、またはSOAサービスを目的とするコンポーネントが必要な場合、今日のEJBは通常「より大きく、強く、速く(または少なくともスケーラブル)およびPOJOよりも単純です。これらは、Webまたは企業ネットワークを介して多数のユーザーにサービスを提供するのに最も価値があり、部門内の小規模アプリにはあまり価値がありません。

  1. Loose Couplingを使用して、複数のアプリケーション/クライアント間でロジックを再利用/共有します。
    EJBは、独自のjarにパッケージ化してデプロイし、多くの場所から呼び出すことができます。それらは一般的なコンポーネントです。確かに、POJOは(慎重に!)ライブラリとして設計し、jarとしてパッケージ化できます。しかし、EJBは、ローカルJavaインターフェース、透過RMI、JMS非同期メッセージ、およびSOAP/REST Webサービスを介したローカルおよびリモートネットワークアクセスの両方をサポートし、複数の(一貫性のない)カットアンドペーストjar依存関係から保存します展開。
    これらは、SOAサービスの作成に非常に役立ちます。ローカルアクセスに使用される場合、POJO(無料のコンテナーサービスが追加されます)です。別のEJBレイヤーを設計する行為は、カプセル化、疎結合、結合を最大化するための特別な注意を促し、きれいなインターフェース(Facade)を促進し、呼び出し元を複雑な処理およびデータモデルから保護します。

  2. スケーラビリティと信頼性さまざまな呼び出しメッセージ/プロセス/スレッドから大量のリクエストを適用する場合、それらは最初にプール内の利用可能なEJBインスタンスに分散され、次にキューに入れられます。これは、1秒あたりの着信要求の数がサーバーが処理できる数よりも多い場合、適切に低下することを意味します。常にいくつかの要求が効率的に処理され、余分な要求は待機させられます。サーバーの「メルトダウン」には到達しません。すべてのリクエストに同時にひどい応答時間が発生し、サーバーはハードウェアとOSが処理できる以上のリソースにアクセスしようとするため、クラッシュします。 EJBは、クラスター化できる別の層に展開できます。これにより、サーバー間でのフェールオーバーによる信頼性が得られ、さらにハードウェアを追加して線形に拡張できます。

  3. 同時実行管理。コンテナは、EJBインスタンスが複数のクライアントによって自動的に安全に(シリアルに)アクセスされるようにします。コンテナは、EJBプール、スレッドプール、呼び出しキューを管理し、メソッドレベルの書き込みロック(デフォルト)または読み取りロック(@Lock(READ)を介して)を自動的に実行します。これにより、書き込みと書き込みの同時衝突によるデータ破損からデータを保護し、読み取りと書き込みの衝突を防ぐことでデータを一貫して読み取ることができます。
    これは主に、Beanがクライアントの呼び出し元間で共通の状態を操作および共有している@SingletonセッションBeanで役立ちます。これを簡単にオーバーライドして、コードの同時実行とデータアクセスの高度なシナリオを手動で構成またはプログラムで制御できます。

  4. 自動トランザクション処理。
    何もせず、すべてのEJBメソッドがJTAトランザクションで実行されます。 JPAまたはJDBCを使用してデータベースにアクセスすると、自動的にトランザクションに参加します。 JMSおよびJCA呼び出しについても同じです。メソッドの前に@TransactionAttribute(someTransactionMode)を指定して、特定のメソッドがJTAトランザクションに参加するかどうか/方法を指定し、デフォルトモード「必須」をオーバーライドします。

  5. インジェクションを介した非常に単純なリソース/依存関係アクセス。
    コンテナは、リソースをルックアップし、リソース参照をEJBのインスタンスフィールドとして設定します。JNDIに保存されたJDBC接続、JMS接続/トピック/キュー、他のEJB、JTAトランザクション、JPAエンティティマネージャー永続コンテキスト、JPAエンティティマネージャーなど工場永続性ユニット、およびJCAアダプターリソース。例えば別のEJBとJTAトランザクションとJPAエンティティマネージャーとJMS接続ファクトリーとキューへの参照を設定するには:

    @Stateless
    public class MyAccountsBean {
    
        @EJB SomeOtherBeanClass someOtherBean;
        @Resource UserTransaction jtaTx;
        @PersistenceContext(unitName="AccountsPU") EntityManager em;
        @Resource QueueConnectionFactory accountsJMSfactory;
        @Resource Queue accountPaymentDestinationQueue;
    
        public List<Account> processAccounts(DepartmentId id) {
            // Use all of above instance variables with no additional setup.
            // They automatically partake in a (server coordinated) JTA transaction
        }
    }
    

    サーブレットは、インスタンス変数を宣言するだけで、このBeanをローカルで呼び出すことができます。

    @EJB MyAccountsBean accountsBean;    
    

    そして、必要に応じてそのメソッドを呼び出すだけです。

  6. JPAとのスマートな相互作用。デフォルトでは、上記のように挿入されたEntityManagerは、トランザクションスコープの永続コンテキストを使用します。これは、ステートレスセッションBeanに最適です。 (ステートレス)EJBメソッドが呼び出されると、新しいトランザクション内で新しい永続コンテキストが作成され、DBに対して取得/書き込みされるすべてのエンティティオブジェクトインスタンスは、そのメソッド呼び出し内でのみ表示され、他のメソッドから分離されます。ただし、他のステートレスEJBがメソッドによって呼び出された場合、コンテナは同じPCを伝播して共有するため、同じエンティティは同じトランザクションでPCを通じて一貫した方法で自動的に共有されます。
    @ StatefulセッションBeanが宣言されている場合、entityManagerを拡張スコープ1として宣言することにより、JPAと同等のスマートアフィニティが実現されます:@PersistentContent(unitName = "AccountsPU、type = EXTENDED)。 Beanセッションの複数のBean呼び出しとトランザクションにまたがって、以前に取得/書き込みされたDBエンティティのメモリ内コピーをキャッシュするため、再取得する必要はありません。

  7. ライフサイクル管理。 EJBのライフサイクルはコンテナ管理です。必要に応じて、EJBインスタンスを作成し、ステートフルセッションBeanの状態をクリアおよび初期化し、ライフサイクルコールバックメソッドを非アクティブ化およびアクティブ化し、EJBコードがリソースを取得および解放するためのライフサイクル操作に参加したり、その他の初期化およびシャットダウン動作を実行したりできるようにします。また、すべての例外をキャプチャし、ログに記録し、必要に応じてトランザクションをロールバックし、必要に応じて新しいEJB例外または@ApplicationExceptionsをスローします。

  8. セキュリティ管理。 EJBへのロールベースのアクセス制御は、単純な注釈またはXML設定を介して構成できます。サーバーは、セキュリティコンテキスト(呼び出しプリンシパルとロール)として、各呼び出しと共に認証済みユーザーの詳細を自動的に渡します。これにより、すべてのRBACルールが自動的に適用され、間違ったロールによってメソッドが不正に呼び出されることがなくなります。これにより、EJBはユーザー/ロールの詳細に簡単にアクセスして、プログラムによる追加チェックを行うことができます。これにより、追加のセキュリティ処理(またはIAMツール)を標準的な方法でコンテナーにプラグインできます。

  9. 標準化と移植性。 EJB実装はJava EE標準とコーディング規約に準拠しており、品質と理解と保守の容易さを促進します。また、すべてが同じ標準機能と動作をサポートすることを保証し、開発者が誤ってプロプライエタリを採用することを阻止することにより、新しいベンダーアプリサーバーへのコードの移植性を促進します。
    非ポータブルベンダー機能。

  10. 本当のキッカー:シンプル。上記のすべては、Java EE 6内のEJBのデフォルト設定を使用するか、いくつかの注釈を追加することにより、非常に合理化されたコードで実行できます。独自のPOJOでエンタープライズ/産業強度機能をコーディングすると、wayよりボリュームが多く、複雑で、エラーが発生しやすくなります。 EJBを使用してコーディングを開始すると、EJBの開発がかなり簡単になり、「フリーライド」の優れたメリットが得られます。

10年前の元のEJB仕様では、EJBは生産性の面で大きな問題でした。それらは肥大化し、多くのコードと構成成果物を必要とし、上記の利点の約2/3を提供しました。ほとんどのWebプロジェクトは実際には使用しませんでした。しかし、これは10年間の微調整、オーバーホール、機能強化、開発のストリームライン化によって大きく変化しました。 Java EE 6では、最大レベルの産業強度と使いやすさを提供します。

好きではないのは何ですか?? :-) :-)

158
Glen Best

EJBは、コンテナにデプロイするビジネスロジックを含むJavaコンポーネントであり、通常はアノテーションのおかげで宣言的な方法でコンテナによって提供される技術サービスの恩恵を受けます。

  • トランザクション管理:トランザクションは、EJBのメソッドが呼び出される前に自動的に開始され、このメソッドが戻ったらコミットまたはロールバックできます。このトランザクションコンテキストは、他のEJBへの呼び出しに伝播されます。
  • セキュリティ管理:メソッドを実行するために必要な役割が呼び出し側にあることを確認できます。
  • 依存性注入:他のEJB、またはJPAエンティティマネージャー、JDBCデータソースなどのリソースをEJBに注入できます。
  • 並行性:コンテナは、一度に1つのスレッドのみがEJBインスタンスのメソッドを呼び出すようにします。
  • 配布:一部のEJBは、別のJVMからリモートで呼び出すことができます。
  • フェールオーバーと負荷分散:EJBのリモートクライアントは、必要に応じて、呼び出しを別のサーバーに自動的にリダイレクトできます。
  • リソース管理:ステートフルBeanは、サーバーのメモリ消費を制限するために、ディスクに自動的にパッシベーションできます。
  • ...おそらくいくつかの点を忘れてしまいました。
65
JB Nizet

Oracleのドキュメントからこれが、EJBのトピックを簡単な方法で理解するのに役立つことを願っています。

エンタープライズBeanとはJavaプログラミング言語で記述されたエンタープライズBeanは、アプリケーションのビジネスロジックをカプセル化するサーバー側コンポーネントです。ビジネスロジックは、アプリケーションの目的を満たすコードです。たとえば、在庫管理アプリケーションでは、エンタープライズBeanはcheckInventoryLevelおよびorderProductと呼ばれるメソッドでビジネスロジックを実装します。これらのメソッドを呼び出すことにより、クライアントはアプリケーションが提供するインベントリサービスにアクセスできます。

エンタープライズBeanの利点いくつかの理由により、エンタープライズBeanは大規模な分散アプリケーションの開発を簡素化します。まず、EJBコンテナはエンタープライズBeanにシステムレベルのサービスを提供するため、Bean開発者はビジネス上の問題の解決に専念できます。 Bean開発者ではなく、EJBコンテナが、トランザクション管理やセキュリティ認証などのシステムレベルのサービスを担当します。

第二に、クライアントではなくBeanにアプリケーションのビジネスロジックが含まれているため、クライアント開発者はクライアントのプレゼンテーションに集中できます。クライアント開発者は、ビジネスルールを実装したり、データベースにアクセスしたりするルーチンをコーディングする必要はありません。その結果、クライアントはより薄くなります。この利点は、小さなデバイスで実行されるクライアントにとって特に重要です。

第三に、エンタープライズBeanは移植可能なコンポーネントであるため、アプリケーションアセンブラは既存のBeanから新しいアプリケーションを構築できます。これらのアプリケーションは、標準APIを使用する限り、準拠するJava EEサーバーで実行できます。

エンタープライズBeanを使用する場合アプリケーションに次の要件がある場合は、エンタープライズBeanの使用を検討する必要があります。

アプリケーションはスケーラブルでなければなりません。増え続けるユーザーに対応するには、アプリケーションのコンポーネントを複数のマシンに分散する必要がある場合があります。アプリケーションのエンタープライズBeanは、異なるマシンで実行できるだけでなく、その場所もクライアントに対して透過的になります。

トランザクションはデータの整合性を確保する必要があります。エンタープライズBeanは、共有オブジェクトの同時アクセスを管理するメカニズムであるトランザクションをサポートします。

アプリケーションにはさまざまなクライアントが含まれます。わずか数行のコードで、リモートクライアントはエンタープライズBeanを簡単に見つけることができます。これらのクライアントは、シン、さまざま、および多数である場合があります。

21
Tesfa Zelalem

私が最も興味を持っている質問は、どのように、どこでそれらを使用できるかです。これを理解するには、まずどのタイプのEJBが存在するかを確認する必要があります。 2つの大きなカテゴリがあります。

  1. セッションBean
  2. メッセージ駆動型Bean

セッションBeanについて考えてみましょう。次の3種類があります。

  1. ステートフル-これらのコンポーネントは状態を維持し、複数のリクエストにわたるクライアントに固有です。セッションとして見てください。これらを直接使用できるのは、ショップカートまたは他のタイプのセッション(ログインセッションなど)です。
  2. ステートレス-これらは、リクエスト間で情報を保持しない自己完結型コンポーネントですが、ユーザーに固有です。すぐに思い浮かぶ使用-サービス層のサービスクラスOrderServiceを想像してください。これらのもう1つの大きな用途は、Webサービスを公開することです。繰り返しますが、これはサービス層にあるか、完全に分離されています。
  3. シングルトン-これらはアプリケーションごとに存在し、一度作成され、複数回再利用/アクセスできるBeanです。すぐにConfigurationコンポーネントが思い浮かびます-アプリケーションレベルの設定を保存し、どこからでも必要なときにそれらにアクセスできます。

このような状況では、残りの機能または機能をレイヤー間で使用できます。

  • セキュリティ-呼び出されたメソッドの注釈を使用して、権限を確認できます。これは、必要に応じて、コントローラーだけでなくサービス層でも発生する可能性があります。
  • トランザクション管理-これは、サービス層または永続層の明らかな候補です
  • 依存性注入-再びどこでも使用されます

現代の大きな用途の1つは、いわゆるマイクロサービスとサービス指向アーキテクチャです。いくつかのビジネスロジックコンポーネントをEJBとしてパッケージ化し、それらを組織全体に配布して、複数のクライアント(ここではクライアントとは、他のバックエンドアプリケーション)が使用できるようにすることができます。

等々。現在の大きな欠点は、EJBコンテナーに非常に依存するようになり、2つの参照実装を切り替えることはできますが、より軽いもの(たとえばTomcat)に切り替えることができないことです。しかし、なぜすべてのメリットを犠牲にしたいのですか?

3
ACV