web-dev-qa-db-ja.com

CDI(溶接)にオブジェクトのリストを挿入します

SocialNetworkServiceというインターフェースと、TwitterServiceFacebookServiceFriendFeedServiceの3つの実装があるとします。

これで、マネージドBean(または任意のWebコンポーネント)がメッセージを受信するたびに、それをすべてのソーシャルネットワークで共有したいと思います。私は試した:

@Inject private List<SocialNetworkService> socialNetworkServices;

しかし、それは機能しませんでした(展開エラー)。 (@Any修飾子も試しました-同じ結果です)

それで、インターフェースのすべて(またはいくつか)の実装のリストを挿入する方法はありますか?

特定の注入ポイントに複数の可能なBeanを含めるべきではないというルールを知っています。リストを作成するプロデューサーを作成し、Instance<SocialNetworkService>を使用することでそれを達成できると思いますが、それはこのタスクには多すぎるようです。

38
Bozho

私の試みとWeldフォーラムからの回答を組み合わせる:

_@Inject @Any
private Instance<SocialNetworkService> services;
_

InstanceIterableを実装しているため、for-eachループを使用するだけで済みます。 _@Any_修飾子が必要です。


これを行う別の方法は、イベントシステムを使用することです。

  • MessageEvent(メッセージに関するすべての情報を含む)を作成します
  • ソーシャルネットワークのリストを挿入する代わりに、単にイベントを挿入します。

    _@Inject private Event<MessageEvent> msgEvent;
    _

    そしてそれを起動します:msgEvent.fire(new MessageEvent(message));

  • すべてのサービスでイベントを監視します(インターフェイスに関係なく、プラスになる可能性があります)。

    _public void consumeMessageEvent(@Observes MessageEvent msgEvent) {..}
    _
67
Bozho

JSR-299の仕様を見てみましたが、やりたいことが簡単にできないようで、この特殊なケースのコードを提供するのに十分なWeldの経験がありません。

ただし、12.3章「Beanの検出」に基づいて、実装を@Alternativeとして宣言し(Weldが複数の実装について文句を言うのを避けるため)、SocialNetworkServiceの実装が見られたときに収集するProcessBeanイベントをリッスンできる場合があります。