2017-09-04 161 views
0

我有兩個班,我想注入:函數在CDI w.r.t中是特別的。 @Inject vs BeanManager.getBeans(Function.class)?

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

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

當我嘗試使用他們在其他地方,我得到不同的行爲:

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)); 

我的輸出是:

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

這是比我預期的少一行。

有人可以解釋這裏發生了什麼?

解決方案,這要歸功於Siliarus設置我走下了正確的道路:

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; 
     } 
    }); 

回答

0

如果我得到你的樣品你缺少正確的是第一線 - 從Function輸出通過BeanManager時獲得。

我的猜測是,Set<Bean<?>> functions是空的。原因是仿製藥Function是一種通用類型,BeanManager上的方法並不是那麼好。 CDI規範很好地定義了Typesafe resolution for parameterized types(儘管需要一些閱讀)。

簡而言之,您的Function<String, String>類型的bean將不能分配給剛生成的Function.class,您將其傳遞給BeanManager方法。作爲一個方面說明,如果你想動態地實例化參數化類型,你總是可以使用Instance<T>,它支持使用TypeLiteral-一種特殊的結構,它不僅保存原始類型,還包含關於原始類型的信息實際參數。

+0

感謝您的回覆。 我在問BeanManager,因爲我想知道關於bean上的其他限定詞,因爲我敢肯定,你猜對於這種類型,最終這將是一個生產者返回一個lambda而不是一個專門的類。 我還不確定如何向函數詢問bean管理器? –

+0

所以通過給BM一些有用的Type信息它很好。我只需要非常明確的參數化類型,帶有兩個通配符類型作爲參數類型。 –

+0

很高興你知道了! :) – Siliarus