1

同様の質問がありましたが、私がやろうとしていることは明らかにしていません。 CDIに変換するバッチジョブフレームワークを持つ古いSeam 2.xベースのアプリケーションがあります。ジョブフレームワークは、Seam Contextsオブジェクトを使用して会話を開始します。ジョブフレームワークは、Seam Contextsオブジェクトを介して、SLSBを含むチェーンを介した任意のサービスによってアクセスできるジョブ固有のデータ所有者(基本的にMap)も読み込みます。これらのサービスの中には、マップを更新できるものがあるため、ジョブの状態が変化し、レコードごとに検出される可能性があります。CDI会話を開始し、ステートレスセッションBeanに@ConversationScoped Beanを注入する

CDIのように、ジョブは@Inject CDI会話オブジェクトになり、手動で会話を開始/終了します。 Map(MapBean)を保持する新しいConversationScoped beanも定義します。

最初に、Conversation.begin()メソッドが呼び出される前にジョブに@MapBeanを注入してジョブ固有のデータをロードできるようにする必要があります。コンテナはこのインスタンスをコールチェーンのサービスに渡すことを知っていますか?

これに関連して、この質問Is it possible to @Inject a @RequestScoped bean into a @Stateless EJB?によると、ConservationScoped beanをSLSBに注入することは可能ですが、少し魔法のようです。 SLSBが別のプロセス(ジョブ、UIコールなど)で使用されている場合、呼び出しごとに個別のインスタンスが取得されますか?明確化および単純化されたクラス構造体の

編集:

MapBeanジョブの特定のインスタンス/実行のためのデータを含む、ConversationScopedオブジェクトであることが必要であろう。

@ConversationScoped 
public class MapBean implements Serializable { 
    private Map<String, Object> data; 
    // accessors 
    public Object getData(String key) { 
     return data.get(key); 
    } 
    public void setData(String key, Object value) { 
     data.put(key, value); 
    } 

} 

ジョブがConversationScoped次のようになります。

@ConversationScoped 
public class BatchJob { 
    @Inject private MapBean mapBean; 
    @Inject private Conversation conversation; 
    @Inject private JobProcessingBean jobProcessingBean; 
    public void runJob() { 
     try { 
      conversation.begin(); 
      mapBean.setData("key", "value"); // is this MapBean instance now bound to the conversation? 
      jobProcessingBean.doWork(); 
     } catch (Exception e) { 
      // catch something 
     } finally { 
      conversation.end(); 
     } 
    } 
} 

ジョブがSLSBを呼ぶかもしれない、とMapBeanニーズの現在の対話スコープのインスタンスが利用できるようにする:

@Stateless 
public class JobProcessingBean { 
    @Inject private MapBean mapBean; 

    public void doWork() { 
     // when this is called, is "mapBean" the current conversation instance? 
     Object value = mapBean.getData("key"); 
    } 
} 

私たちの仕事SLSBフレームワークは非常に複雑ですが、SLSBは他の多くのサービスやローカルでインスタンス化されたビジネスロジッククラスを呼び出すことができ、これらのそれぞれは会話にアクセスする必要があります-scoped MapBean

+0

要約:はいとはい。あなたのデザインは一般的にうまくいくはずです。今日後で試して回答を投稿する必要があります。 – user1803551

答えて

2

まず、Conversation.begin()メソッドが呼び出される前に、ジョブ固有のデータをロードすることができるように、仕事もMapBean@Injectする必要があります。コンテナはこのインスタンスをコールチェーンのサービスに渡すことを知っていますか?

はい、MapBeanは、それがconversation.end()までconversation.begin()から始まる期間のコールチェーンに結合されている@ConversationScopedからです。 @ConversationScoped(および@RequestScoped@SessionScoped)は、ThreadLocalのインスタンスとして考えることができますが、すべてのスレッドに対してインスタンスが存在しますが、各インスタンスはその単一のスレッドに関連付けられています。それに関連し

、この質問Is it possible to @Inject a @RequestScoped bean into a @Stateless EJB?によると、SLSBに@ConservationScoped Beanを注入することが可能でなければなりませんが、それは少し魔法のようです。 SLSBが別のプロセス(ジョブ、UIコールなど)で使用されている場合、呼び出しごとに個別のインスタンスが取得されますか?

このパターンは、私が上で説明したものと同じであることがわかると、それほど魔法的ではありません。 SLSBは実際には別のインスタンスを取得しますが、インスタンスだけでなく、SLSBが呼び出されたスコープに属するインスタンスも取得されます。

投稿したリンクに加えて、this answerも参照してください。

あなたが投稿したものと同様のコードがIv'eでテストされ、期待通りに機能します。MapBeanは通話中に注入された同じものです。わずか2つの物事に注意してください:

  • BatchJob@ConversationScopedですが、Beanが不動態化することはできませんSerializableを実装していません。
  • dataは初期化されていないので、runJob()にNPEが表示されます。
+0

ありがとうございました。「有用な」数を試しましたが、まだ十分な担当者がいません。 – whafrog

+0

@whafrog質問は解決したことを示すために、受け入れられた回答(緑色のチェックマーク)を選択することは重要です。あなたはまた、そうするために2ポイントを得る。 – user1803551

+0

受け入れられたように答えると、私にはちょうどいいと言われました。:) – whafrog

0

コードサンプルがなければ、私はいくつかの推測をしなければならないので、私があなたを正しく見てみましょう。

コンテナは、このインスタンスをコールチェーンのサービスに渡すことを知っていますか?

通話の他の場所で同じインスタンスを使用することを意味する場合、これは容易MapBean@ApplicationScoped豆(又は、代替的に、およびEJB @Singleton)を製造することによって達成することができます。

ConservationScoped BeanをSLSBに挿入することは可能ですが、少し魔法のようです。

ここで、私は、SLSBがCDIの意味で「@Dependent」のBeanであると思われる理由を推測します。そして、あなたが知っているように、CDIは常に依存するBeanインジェクションポイント用の新しいインスタンスを作成します。例えば。はい、呼び出しごとに異なるSLS/Dependent Beanインスタンスが取得されます。

多分、他のスコープがあなたの方にうってつけでしょうか? @RequestScopedまたは@SessionScopedのように?詳細な説明なしには難しい。

+0

応答をいただき、ありがとうございました。質問を単純化したクラス構造で更新しました。私のフレームワークを書き直すことはできますが、大規模なプロジェクトなので、Seamを取り除きCDIで置き換える最も簡単な方法を見つけなければなりません。 – whafrog

+0

@whafrogわかりました。それは私が最初に理解したものとはかなり異なっています。とにかく、両方の質問への答えは "はい"でなければなりません.2つの会話スコープの豆は間違いなく一緒に働くはずです。また、ステートレスBeanに会話スコープ1を挿入できます。あなたのために働かないものがありますか? – Siliarus

+0

確認してくれてありがとう、私はまだ単純化されたPOCを使って作業していますが、少なくとも私は正しい道にいるようです。私が今解決しようとしている1つの詳細は、古いシステムではBatchJobもJMX Beanとして登録されているため、バッチスケジューラからリモートで呼び出せるということです。だから私はBatchJobを呼び出す別のBeanにJMXの部分をリファクタリングする必要があると思います(@ConversationScopedで動作することはありません)。私はまだBatchJobに会話を開始したいので、BatchJobをJmxBeanに注入しないと思いますが、私は新しいインスタンスを作成します...? – whafrog

関連する問題