CDIには、@ApplicationScoped
および(javax.inject
)@Singleton
疑似スコープがあります。それらの違いは何ですか? @ApplicationScoped
はプロキシ化され、@Singleton
はプロキシ化されないという事実に加えて。
@Singleton
Beanを@ApplicationScoped
に変更することはできますか? @ApplicationScoped
Beanは2つ(またはそれ以上)のインスタンスを持つことができますか?
@Singleton
はCDI仕様の一部ではありません。 EJBの一部であり、javax.inject
(JSR-330)。仕様にはその動作が記載されていないため、Weldドキュメントに記載されている内容のみに依存できます。
要するに:それを混ぜることもできます(@Singleton
および@ApplicationScoped
)いくつかのシナリオでは意味があります。(そして、私の期待どおりに動作します!)
これまでの他の回答に加えて、現実世界のシナリオで明確にするために、さらにポイントを追加したいと思います。
私にとって、この質問は から発展しました。アプリケーションスコープのBeanをアプリケーションの起動時にインスタンス化させるにはどうすればよいですか? これまでのところ:
多くの実際のシナリオ/設定では、抽象/モデリングの観点から-何かがあるか(または扱われるようになるか)を明確に言うのは難しいと言いますEJBまたはアプリケーションスコープのマネージドBean
(議論の余地はないが、決定的なものではない)これまでの議論(私の観点から):(@BalusCおよびその他すべて:決定的なものになりたいのですが、そうでない場合は、上記が当てはまる可能性があります。それでも読者が違い/利点/欠点/悪い/良い習慣をつかむのを助けます)
BalusC:これはマネージドBeanではなくEJBであり、まったく異なります。 EJBはバックエンドで実行され、マネージドBeanはフロントエンドで実行されます。 EJBもトランザクションコンテキストで実行されます。 [...]エンタープライズBeanとマネージドBeanを混同しただけで、それを指摘しました。
しかし:
me:あなたはあまり正確ではなく、意味/使用法を誇張していると思います。 http://en.wikipedia.org/wiki/Enterprise_JavaBeans
Enterprise JavaBeans(EJB)は、エンタープライズソフトウェアのモジュール構成のための管理されたサーバーソフトウェアであり、いくつかのJavaAPI。EJBは、ビジネスをカプセル化するサーバー側ソフトウェアコンポーネントです。アプリケーションのロジック。
エンタープライズBeanのタイプ
「ステートフル」、「ステートレス」、または「シングルトン」のいずれかである可能性のあるセッションBean [
メッセージ駆動型Bean [...]
...これは私の場合はまだ当てはまります。
BalusC:シングルトンEJBは、アプリケーションスコープBeanとは異なります。シングルトンEJBは読み取り/書き込みがロックされているため、念頭に置いたタスクに対して非効率的/過度に複雑になる可能性があります。長い話:良いJava EEの本を入手し、仕事に適切なツールを使用する方法を学んでください。1つの方法は間違いなく他の方法ではありません。スレッジハンマーはネジを締めることができますが、必ずしも適切なツールとは限りません:)
しかし:
(ここにハンマーが表示されません-ごめんなさい...)ロックのデフォルトを知っているのは良いことです(私はそれを知りませんでした)が、これは再び間違っているようです: Oracle Java EE 6チュートリアル on シングルトンセッションBeanでの同時アクセスの管理
シングルトンセッションBeanを作成する場合、シングルトンのビジネスメソッドへの同時アクセスは、コンテナ管理の同時実行とBean管理の同時実行の2つの方法で制御できます。 [...]
デフォルトでは、シングルトンはコンテナ管理の同時実行を使用しますが、@ ConcurrencyManagement(CONTAINER)アノテーションをシングルトンのクラスレベルで追加して、同時実行管理タイプを明示的に設定できます
JSR-299の@Singleton
は、シングルトンと呼ばれる組み込みスコープのJSR-299管理対象Beanではなく、シングルトンセッションBean(javax.ejb.Singleton
ではなくjavax.inject.Singleton
)を指します。
サーバーでは、@ApplicationScoped
がEARごとに1つ、またはWAR/EJB-JARごとに1つであることが仕様で明確ではないことがわかりますが、JVMごとに1つになるとは期待しないでください。
通常、オブジェクトのインスタンスを1つだけにしたい場合は、おそらく@ApplicationScoped
注釈-そのようなオブジェクトはプロキシされているため、すぐに適切にシリアル化できます。
一方、クラスのインスタンスが1つだけ必要な場合も多くありますが、そのようなクラスはプロキシできない(たとえば、最終クラスであるため)-@Singleton
は救助です。 Singleton
は擬似スコープであり、「通常の」スコープのようにプロキシされないためです。
もう1つ違いがあります:Singleton
スコープは通常のスコープではないため、@Singleton
はBean定義アノテーションではありません。 @ApplicationScoped
は、Bean定義アノテーションです。
CDI 1.1仕様の場合:discovery-mode = annotatedのアプリケーションの場合、Weldは@Singleton
でBeanを識別せず、これをロードしません
デフォルトの請負業者でクラスを作成できる主な違いの1つは、javax.inject.Singleton
を使用する場合はプライベートアクセス修飾子がありますが、javax.enterprise.context.ApplicationScoped
を使用する場合は少なくともデフォルトのアクセス修飾子を持つデフォルトの請負業者が必要であり、これはJBOSS 6.1 GA Final
実装です