2016-04-13 15 views
2

Wildfly/JBoss Weld/CDI 1.1を使用して作業する。CDIダイナミックBeanインスタンス

データベースがあるとします。何でもかまいませんが、MySQL、MongoDB。 RESTサービスである可能性があります。そのデータベースから、あなたは動物のリストを取得します。

あなたはこのサービスからどのような動物が得られるのかわかりませんが、あなたがしたいことはインスタンス注入のために利用できるようにすることです。

動物クラス:

public class Animal { 
    private final String type; 
    public String getType() { 
    return type; 
    } 
    public Animal(String aType) { 
    type = aType; 
    } 
} 

注入点:

@Produces @AnimalType 
public Animal makeAnimal(InjectionPoint ip) { 
    // Get AnimalType qualifier and make a new Animal(typeString), 
    // ... 
    return animal; 
} 

@Inject @Any 
public Instance<Animal> animals; 

あなたは、特定の動物を作るために修飾子を指定して、たとえば、動物を作るプロデューサメソッドを作ることができます

しかし、どのようにしてすべての(データから知られている)動物を作って、インスタンスでそれらを反復できるようにしますか?

for(Animal animal : animals) { 
    // ... 
} 

私は各動物が依存性注入およびその他のウェルド/ CDIの利点を得ることを望んでいます。

答えて

1

あなたはUnmanaged

Unmanaged<Animal> unmanagedAnimal = new Unmanaged<>(Animal.class); 
UnmanagedInstance<Animal> animalInstance = unmanagedAnimal.newInstance(); 
Animal animal = animalInstance.produce().inject().postConstruct().get(); 

基本的にその依存スコープのBeanが、あなたが行われたときに、手動でそれを破壊する必要が探しているかもしれないように思えます。

+0

アンマネージを注入することができます。ここで必要なのは、動物をどこにでも注射できることです。アンマネージドではそれでは不十分です。唯一の解決策は、これらの動物の豆を作ることです... –

0

私がInjectionPointの概念を理解している限り、そのようにインスタンスと共に使用することはできません。プロデューサメソッドとインスタンスとInjectionPointはInjectionPointに応じて、すべてのCDI-動物とプロデューサメソッドに

Instance<Animal> 

を注入し戻すためにどの動物、プロデューサ方法を決定させるために使用される。

public Animal make(@Any Instance<Animal> instance, InjectionPoint ip) 

はここhttps://dzone.com/articles/cdi-di-p2

のような予選-CONFIG-入力に応じて、 https://www.javacodegeeks.com/2013/06/java-ee-cdi-programmatic-dependency-disambiguation-example-injection-point-inspection.html

または構成され、オブジェクトを生成するために、ここにも参照してください。あなたのケースでは

あなたはプロデューサメソッドを見つける方法を、CDIを伝える必要があります。

@Qualifier 
    @Retention(RUNTIME) 
    @Target({TYPE, METHOD, FIELD, PARAMETER}) 
    public @interface AnimalType { 
     String value(); 
    } 

その後、あなたは適切なプロデューサメソッド書き込むことができます。

@Produces 
@AnimalType("Monkey") 
public Animal makeAnimalApe() { 
    return new Animal("Cheetah"); 
} 


@Produces 
@AnimalType("Mouse") 
public Animal makeAnimalMouse() { 
    return new Animal("Jerry"); 
} 

@Produces 
@AnimalType("Cat") 
public Animal makeAnimalCat() { 
    return new Animal("Tom"); 
} 

をそしてあなたはそれを注入することができます:

@Inject 
@Any 
private Instance<Animal> anyAnimal; 

@Inject 
@AnimalType("Monkey") 
private Animal monkey; 

@PostConstruct 
public void create(){ 
    System.out.println(monkey.name); 
    anyAnimal.forEach((a)->System.out.println(a.name)); 
} 

しかし、この場合は、それぞれの選択ケースに対してプロデューサメソッドを記述する必要があります。私は恐れる、それは適切ではない。

あなたはInjectionPoint使用する必要がありますあなたがAnimalType、NOTを作ることができ、予選今

@Retention(RUNTIME) 
@Target({TYPE, METHOD, FIELD, PARAMETER}) 
public @interface AnimalType { 
    String value(); 
} 

をInjectionPointを使用するには:

@Produces 
public Animal makeAnimalApe(InjectionPoint p) { 
    AnimalType t = p.getAnnotated().getAnnotation(AnimalType.class); 
    if (t != null) { 
     String s = t.value(); 
     if ("Monkey".equals(s)) 
      return new Animal("Cheetah"); 
     else if ("Mouse".equals(s)) 
      return new Animal("Jerry"); 
     else if ("Cat".equals(s)) 
      return new Animal("Tom"); 
    }  
    throw new EJBException("Please annotate the animal injection point with AnimalType"); 
} 

をしかし、あなたはあなたのBeanにインスタンスを注入することができないための欠如修飾子のAnimalType。ですから、このような単純なリストを生成する必要があります。

@Produces 
public List<Animal> produceAll(){ 
    List<Animal> all = new ArrayList<>(); 
    all.add(new Animal("Cheetah")); 
    all.add(new Animal("Jerry")); 
    all.add(new Animal("Tom")); 
    return all; 
} 

だから、あなたはそれが注射対象に非Beanクラスを変換するために使用さだけで一つまたは全て

@Inject 
@AnimalType("Monkey") 
private Animal monkey; 
@Inject 
private List<Animal> all; 
関連する問題