2012-06-21 11 views
7

とジェネリックJSR-299の仕様状態を制限:は§3.1でCDI

マネージドBeanクラスはジェネリック型である場合、それはスコープ @Dependentを持っている必要があります。パラメータ化されたBeanクラスを持つマネージドBeanが@Dependent以外のスコープを と宣言した場合、コンテナは自動的に を検出し、定義エラーとして処理します。効果的にあなたがこれを行うことができないことを意味する

@Named 
@SessionScoped or @RequestScoped or similar 
public class MyProducer<T> {...} 

この決定のための技術的な理由は何ですか?

万が一CDIの次期バージョンで是正されますか?

これに対処/対応するためのベストプラクティスはありますか?私は頻繁に使用することができます回避策は必要なスコープを持つBeanに一般的なPOJO-Beanを注入することである -

はあなたに

EDITありがとうございます。しばしば、必ずしもそうではありません。

+0

ところで、大きな質問です。私はこの制限について知らなかったし、それは本当にあなたの考えを得る。 –

答えて

13

はここで一般的な、非依存のBeanクラスです:

@ApplicationScoped 
public class FavouriteChooser<T> { 
    public T getFavourite() { 
     // ... 
    } 
} 

このBeanのインスタンスがアプリケーションに存在しますどのように多くの?ここで

は、注射部位である:

@Inject 
private FavouriteChooser<String> favouriteWord; 

そして、ここでは別です:

@Inject 
private FavouriteChooser<Integer> favouriteNumber; 

は、あなたの答えを変更しますか? :

@Inject 
private FavouriteChooser<CharSequence> favouriteLetters; 

EDIT:D

ああ、ここでは別です。ソリューションが必要な場合は、ジェネリッククラスの抽象クラスを作成し、そのタイプをバインドする具象サブクラスを追加することをお勧めします。したがって:

public abstract class MyProducer<T> {...} 

@Named 
@SessionScoped 
public class MyStringProducer extends MyProducer<String> {} 

@Named 
@SessionScoped 
public class MyIntegerProducer extends MyProducer<Integer> {} 

これは定型ですが、タイプごとに3行しかありません。あなたが望むかもしれないタイプごとにセッションごとに1つのインスタンスを与えることを覚えておいてください。

+0

ニース - 名前のついた豆を作っていない限り、注入できますか?スコープが保存されている場合(つまり、それぞれFavouriteChooserアプリケーションスコープで注入されていますか?)、唯一の制限よりもELエクスプレッションでアクセスできないことがありますか?そして、それは仕様と矛盾していませんか?結局のところ、マネージドBeanであるはずです。 – kostja

+3

いいえ、私の主張は、このコードはおそらく動作しないことです!私は 'FavouriteChooser'アプリケーションスコープを宣言しました。つまり、インスタンスが1つしか存在できません。しかし、同じ物体で*満たすことができない2つの注射部位があります*。それは、ジェネリッククラスのインスタンスを依存型以外のスコープに挿入できない理由です –

+0

この回答を書いたときに何を言っているのかが分かりません。私はちょうどそれを正しく説明する時間がなくて急いだ。 –

2

非依存スコープBeanをプロキシする必要があります - AFAIKこれはジェネリック型では不可能です。

UPDATE:

私は、より詳細にそれを説明できるのが大好きですが、私はありません;-)溶接はjavassistを使用していますよ、と彼らは述べることproxying generic types is possible in principle - 直接トップレベルAPIでサポートされていないが、 。しかし、我々は仕様については、溶接の実装ではなく、話している...

多分誰かがギャップを埋めることができますか?

+0

ありがとう、ジャン。それはすでに問題を軽視しています。なぜジェネリック型がプロキシできないのか説明することができれば嬉しいです(私はそれが主なjava nemesis型消去と関係があると思いますが、私の指を置くことはできません)。 – kostja