我有两个课程,我想注入:
@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 :(得分:0)
如果我正确地得到了您的样本,那么第一行 - 通过Function
获得BeanManager
时的输出。
我的猜测是,Set<Bean<?>> functions
是空的。原因是泛型。 Function
是一种通用类型,BeanManager
上的方法并不是很好。 CDI规范很好地定义了Typesafe resolution for parameterized types(虽然需要一些阅读)。
简而言之,您的Function<String, String>
类型的bean不能分配给原始Function.class
,您可以将其传递给BeanManager
方法。
作为旁注,如果您希望即时实例化参数化类型,您可以始终使用Instance<T>
,它支持使用TypeLiteral
- 一种特殊的构造,它不仅包含原始类型,还有关于实际参数的信息。