CDI w.r.t 中的函数是特殊的吗? @Inject 与 BeanManager.getBeans(Function.class)?

Are Functions special in 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;
        }
    });

如果我正确地得到了你的样本,你所缺少的是第一行 - 通过 BeanManager.

获得时 Function 的输出

我猜 Set<Bean<?>> functions 是空的。原因是 泛型 Function 是一个通用类型,BeanManager 上的方法不太适合它。 CDI 规范很好地定义了 Typesafe resolution for parameterized types(尽管需要一些阅读)。

简而言之,您的 Function<String, String> 类型的 bean 将不能仅分配给您传递给 BeanManager 方法的原始 Function.class

附带说明一下,如果您希望即时实例化参数化类型,您始终可以使用 Instance<T>, which supports the use of TypeLiteral - 一种特殊结构,它不仅包含原始类型,还包含有关实际类型的信息参数.