2017-09-04 1 views
0

Ich habe zwei Klassen, die ich injizieren wollen:Sind Funktionen speziell in CDI w.r.t. @Inject vs BeanManager.getBeans (Funktion.class)?

@ApplicationScoped 
public class BeanThing { 
    public String apply(String s) { 
     return "bt(" + s + ")"; 
    } 
} 

und

@ApplicationScoped 
public class ClassFunction implements Function<String, String> { 
    @Override 
    public String apply(String s) { 
     return "cf(" + s + ")"; 
    } 
} 

Wenn ich versuche, und ihnen, dass ich ein anderes Verhalten bekommen anderswo verwenden:

Set<Bean<?>> functions = beanManager.getBeans(Function.class); 
    for (Bean<?> untyped : functions) { 
     Bean<Function<String, String>> typed = (Bean<Function<String, String>>) untyped; 
     Function<String, String> function = beanManager.getContext(typed.getScope()).get(typed, beanManager.createCreationalContext(typed)); 
     System.err.println(function.apply("beanManager")); 
    } 

    Set<Bean<?>> beanThings = beanManager.getBeans(BeanThing.class); 
    for (Bean<?> untyped : beanThings) { 
     Bean<BeanThing> typed = (Bean<BeanThing>) untyped; 
     BeanThing beanThing = beanManager.getContext(typed.getScope()).get(typed, beanManager.createCreationalContext(typed)); 
     System.err.println(beanThing.apply("beanManager")); 
    } 

    System.err.println(injectedFunction.apply("injected")); 
    System.err.println(beanThing.apply("injected")); 
    System.err.println("injectedFunction is a function: " + (injectedFunction instanceof Function)); 

mein Ausgang :

bt(beanManager) 
cf(injected) 
bt(injected) 
injectedFunction is a function: true 

Das ist eine Zeile weniger als ich erwarte.

Könnte jemand erklären, was hier vor sich geht?

Lösung, dank Siliarus für mich weg auf der rechten Pfad einstellen:

Set<Bean<?>> functions = beanManager.getBeans(new ParameterizedType() { 

     @Override 
     public Type[] getActualTypeArguments() { 
      return new Type[]{new WildcardType() {...}, new WildcardType() {...}; 
     } 

     @Override 
     public Type getRawType() { 
      return Function.class; 
     } 
    }); 

Antwort

0

Wenn ich Ihre Probe erhalten richtig, was Sie vermissen ist die erste Zeile - Ausgabe aus dem Function wenn über BeanManager erhalten.

Meine Vermutung ist, dass die Set<Bean<?>> functions leer ist. Der Grund dafür sind Generika. Function ist ein generischer Typ und Methoden auf BeanManager sind nicht wirklich gut damit. CDI-Spezifikation definiert Typesafe resolution for parameterized types ziemlich gut (obwohl es etwas liest).

Kurz gesagt, Ihre Bean vom Typ Function<String, String> kann nicht nur Function.class zugewiesen werden, die Sie an die Methode BeanManager übergeben. Als Randnotiz können Sie immer Instance<T> verwenden, wenn Sie instantiierte parametrisierte Typen instanziieren möchten, die die Verwendung von TypeLiteral unterstützen - ein spezielles Konstrukt, das nicht nur den Rohtyp, sondern auch Informationen darüber enthält die tatsächlichen Parameter.

+0

Danke für die Antwort. Ich frage den BeanManager, weil ich über die anderen Qualifier auf der Bohne wissen möchte, da ich sicher bin, dass Sie angesichts der beteiligten Typen davon ausgehen, dass ein Produzent schließlich einen Lambda anstatt einer dedizierten Klasse zurückgeben wird. Ich bin immer noch unsicher, wie man den Bean-Manager nach der Funktion fragt? –

+0

Also, indem Sie dem BM ein paar nützliche Type Informationen gaben, war es in Ordnung. Ich musste nur sehr explizit, ParametrizedType, mit zwei WildcardTypes als argumentTypes sein. –

+0

Froh, dass du es herausgefunden hast! :) – Siliarus