はい、CDIとEJBの両方を自由に組み合わせて、すばらしい結果を得ることができます。それはあなたが使用しているように聞こえる@WebService
と@Schedule
ミックスにEJBを追加するための十分な理由です。
そこには多くの混乱があるので、EJBとCDIがそれぞれに関連しているため、EJBとCDIに関する一般的な情報をいくつか示します。
EJB> = CDI
EJB は CDI Beanであるため、CDIのすべての利点があることに注意してください。逆は(まだ)真実ではありません。そのため、「EJB対CDI」を考える習慣をつけないでください。そのロジックは、「EJB + CDI対CDI」に変換されます。これは、奇妙な方程式です。
Java EEの将来のバージョンでは、それらの調整を続けます。整合とは、上部に@Stateful
、@Stateless
または@Singleton
注釈がなくても、人々がすでに実行できることを実行できるようにすることです。
実装規約におけるEJBおよびCDI
最終的に、EJBとCDIは、プロキシされるコンポーネントと同じ基本設計を共有します。EJBまたはCDI Beanへの参照を取得する場合、それは実際のBeanではありません。むしろ、あなたに与えられたオブジェクトは偽物(プロキシ)です。この偽オブジェクトのメソッドを呼び出すと、呼び出しはコンテナーに送られ、コンテナーはインターセプターやデコレーターなどを介して呼び出しを送信し、トランザクションやセキュリティチェックを処理します。すべての処理が完了すると、呼び出しは最終的に実際のオブジェクトに送られ、結果はプロキシを介して呼び出し元に返されます。
違いは、呼び出されるオブジェクトの解決方法のみです。「解決された」とは、コンテナーが呼び出す実際のインスタンスをどこでどのように探すかを単に意味します。
CDIでは、コンテナーは「スコープ」内を検索します。これは、基本的には特定の期間(リクエスト@RequestScoped
ごと、HTTPセッション@SessionScoped
ごと、アプリケーションごと@ApplicationScoped
、JSF会話@ConversationScoped
ごと、またはカスタムスコープの実装ごと)存続するハッシュマップです。
EJBでは、Beanがタイプの場合、コンテナはハッシュマップも調べ@Stateful
ます。@Stateful
豆はまた、スコープ内の他のすべての豆と一緒に暮らすと死なせる上記範囲の注釈のいずれかを使用することができます。EJB @Stateful
では、本質的に「任意のスコープ」のBeanです。これ@Stateless
は基本的にインスタンスプールです。1回の呼び出しの間、プールからインスタンスを取得します。@Singleton
本質的です@ApplicationScoped
基本的なレベルでは、「EJB」Beanで実行できることはすべて「CDI」Beanで実行できるはずです。カバーの下でそれらを区別することはひどく難しいです。インスタンスの解決方法を除いて、すべての配管は同じです。
現在、このプロキシを実行するときにコンテナーが提供するサービスに関しては同じではありませんが、私が言うように、Java EE仕様レベルで取り組んでいます。
パフォーマンスノート
「軽い」または「重い」精神的なイメージは無視してください。それがすべてのマーケティングです。ほとんどの場合、内部設計は同じです。CDIインスタンスの解決は、やや動的で状況依存であるため、おそらくもう少し複雑です。EJBインスタンスの解決は、比較的静的で、無意味で、比較すると単純です。
TomEEの実装の観点から、EJBの呼び出しとCDI Beanの呼び出しの間にパフォーマンスの違いはほとんどないことがわかります。
デフォルトはPOJO、次にCDI、次にEJB
もちろん、メリットがない場合はCDIやEJBを使用しないでください。インジェクション、イベント、インターセプター、デコレーター、ライフサイクルトラッキングなどが必要になったら、CDIを投入します。それはほとんどの時間です。
これらの基本を超えて、CDI BeanにEJBを追加するか@Stateful
、追加する@Stateless
か、または追加することによってのみCDI Beanを作成する場合にのみ使用できる便利なコンテナーサービスがいくつかあります@Singleton
。
EJBを分割するときの短いリストを次に示します。
JAX-WSの使用
JAX-WSの公開@WebService
。私は怠け者。が@WebService
EJBでもある場合は、それをリストして、サーブレットとしてweb.xml
ファイルにマッピングする必要はありません。それは私にとって仕事です。加えて、私は以下に述べる他の機能のいずれかを使用するオプションを取得します。だから私にとっては非常に簡単です。
利用可能@Stateless
と@Singleton
のみ。
JAX-RSの使用
を介したJAX-RSリソースの公開@Path
。私はまだ怠惰です。RESTfulサービスがEJBでもある場合、再び自動検出が行われ、それをJAX-RS Application
サブクラスなどに追加する必要はありません。さらに@WebService
、下記の優れた機能を使用したい場合、または使用したい場合とまったく同じBeanを公開できます。
利用可能@Stateless
と@Singleton
のみ。
起動ロジック
起動時にロードする@Startup
。現在、CDIにはこれに相当するものはありません。どういうわけかAfterStartup
、コンテナーライフサイクルにイベントのようなものを追加するのに失敗しました。私たちがこれを実行した場合@ApplicationScoped
、それをリッスンするBeanがあり、実際には@Singleton
withと同じ@Startup
でした。CDI 1.1のリストに含まれています。
@Singleton
のみご利用いただけます。
並行して作業する
@Asynchronous
メソッド呼び出し。スレッドを開始することは、どのサーバー側環境でも禁止事項です。スレッドが多すぎると、パフォーマンスが大幅に低下します。このアノテーションにより、コンテナーのスレッドプールを使用して行う処理を並列化できます。これは素晴らしいです。
利用可能な@Stateful
、@Stateless
と@Singleton
。
スケジュール作業
@Schedule
またはScheduleExpression
基本的にcronまたはQuartz
機能です。また、とても素晴らしいです。ほとんどのコンテナは、このためにカバーの下でクォーツを使用しています。ただし、ほとんどの人は、Java EEでの作業のスケジューリングがトランザクションであることを知りません。データベースを更新してからいくつかの作業をスケジュールし、そのうちの1つが失敗した場合、両方が自動的にクリーンアップされます。EntityManager
永続呼び出しが失敗した場合、またはフラッシュに問題がある場合、作業のスケジュールを解除する必要はありません。ええ、トランザクション。
利用可能@Stateless
と@Singleton
のみ。
JTAトランザクションでのEntityManagerの使用
もちろん、トランザクションに関する上記の注記では、JTA
マネージドを使用する必要がありますEntityManager
。プレーンな「CDI」でそれらを使用できますが、コンテナ管理のトランザクションなしでは、UserTransaction
コミット/ロールバックロジックを単調に複製できます。
CDI、JSFなど、すべてのJava EEコンポーネントに利用可能な@ManagedBean
、@WebServlet
、@WebListener
、@WebFilter
、など@TransactionAttribute
のアノテーションは、しかし、に利用できる@Stateful
、@Stateless
と@Singleton
だけ。
JTAを管理し続ける EntityManager
EXTENDED
管理は、EntityManager
あなたが保つことを可能にするEntityManager
間、オープンをJTA
キャッシュされたデータが失われたトランザクションはありません。適切な時間と場所に適した機能。責任を持って使用してください:)
@Stateful
のみご利用いただけます。
簡単な同期
同期が必要な場合、@Lock(READ)
および@Lock(WRITE)
アノテーションは非常に優れています。それはあなたが無料で同時アクセス管理を取得することができます。すべてのReentrantReadWriteLock配管をスキップします。同じバケットには@AccessTimeout
があります。これにより、スレッドがBeanインスタンスへのアクセスを取得するまで待機する時間を指定できます。
@Singleton
Beanでのみ使用できます。