2017-09-04 33 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