2016-04-27 19 views
1

私はインターフェイスJava Beanが複合注入

public interface Abstraction { 
    void execute(); 
} 

を持っている私は、複合実装を構築し、Beanとして登録され、このオブジェクトになるように、私はそれを設定するにはどうすればよい@Named

@Named 
public class Composite implements Abstraction { 
    private List<Abstraction> list; 

    @Inject 
    public Composite(List<Abstraction> list) { 
     this.list = list; 
    } 

    public void execute() { 
     list.forEach(Abstraction::execute); 
    } 
} 

をしたいしています抽象クラスへの実装セットは、上記コンポジットに適切に注入されますか?私は依存として抽象化を取る別のオブジェクトを持っているでしょうし、上記の2つの実装で上記の@Namedコンポジットを受け取りたいと思っています。

public class Implementation1 implements Abstraction { 
    public void execute() { } 
} 

public class Implementation2 implements Abstraction { 
    public void execute() { } 
} 
+0

いつも2になるのですか?それらを名前で別々に注入するだけです。 – Savior

+0

@Pillarそれは私の特別な場合、私はそれを行うことができますが、私は各実装に '名前付き'注釈を置くことができないので、どのように確信していません。すみません、私はJava Beanの世界では初めてです。 –

答えて

1

実装ごとに1つのBeanを作成した場合、その例はそのまま使用できます。例えば、@Named@Componentであなたの実装に注釈を付けると、スキャンのためにそれらをマーク(コンポーネントがそのパッケージをスキャン)

@Configuration 
@ComponentScan 
public class StackOverflow { 
    public static void main(String[] args) throws Exception { 
     AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(StackOverflow.class); 
     System.out.println(ctx.getBean(Composite.class).list); 
    } 
} 

interface Abstraction { 
    void execute(); 
} 

@Named 
class Composite implements Abstraction { 
    List<Abstraction> list; 

    @Inject 
    public Composite(List<Abstraction> list) { 
     this.list = list; 
    } 

    public void execute() { 
     list.forEach(Abstraction::execute); 
    } 
} 

@Named 
class Implementation1 implements Abstraction { 
    public void execute() { 
    } 
} 

@Named 
class Implementation2 implements Abstraction { 
    public void execute() { 
    } 
} 

Compositeのリストの両方の実装が含まれます。

また、実装が2つしかないため、Beanに名前を付けて別々に注入することもできます。例

@Component("one") 
class Implementation1 implements Abstraction { 
    public void execute() { 
    } 
} 

@Component("two") 
class Implementation2 implements Abstraction { 
    public void execute() { 
    } 
} 

Composite

List<Abstraction> list = new ArrayList<>(2); 

@Inject 
public Composite(@Qualifier("one") Abstraction one, @Qualifier("two") Abstraction two) { 
    list.add(one); 
    list.add(two); 
} 

でそれらを注入するために、私はちょうどAbstraction豆の初期化の順序がめちゃくちゃにあなたのコンテキストの初期化をする可能性があるため、この解決策を提案します。たとえば、Implementation1が何らかの形でCompositeの初期化に依存していたとすると、文脈は不平を言います。これはまれで、他の方法で制御できます。それでも、この場合、豆について明白になることは明らかでしょう。

+0

あなたの最初のシナリオは私の場合に適用できます。抽象リストが私のコンポジットのために設定される順序は気にしません。しかし、コンポジットBeanを作成すると実際には他の2つの実装がうまくいきますが、「抽象化」に依存する別のBeanを作成しようとすると、コンポジットを注入する必要があることがどのようにわかりますか?この場合、エラーが発生します: '予想される単一の一致するbeanですが、found 3:implementation2、composite、implementation1' –

+0

@JonEricksonそれを名前で修飾し、その名前を注入ポイントで使用する必要があります。あるいは、 'CompositieAbstract'のような'抽象化 'のサブタイプである別のインターフェースを定義し、' Composite'にそれを実装させて、それに対して注入します。 – Savior

+0

gotcha、コンポジットに 'N​​amed("コンポジット ")アノテーションを追加して、' Qualifier( "コンポジット")アノテーションを他のオブジェクトのコンストラクタパラメータに追加しました。ご協力いただきありがとうございます –

関連する問題