java - 我必须使用什么类型的文字才能使 CDI 的 Instance::select 方法正常工作?

标签 java cdi

假设我有这样一个界面:

public interface Converter<T> { /*...*/ }

假设在 CDI 环境中我已经成功地做到了这一点:

@Inject
@Any
private Instance<Converter<?>> converters;

(“成功”是指我可以执行以下操作并在输出中看到多个转换器,因此可以正确发现和提供 bean:

for (final Object o : converters) {
  System.out.println("*** converter: " + o);
}

...所以 bean 发现不是问题。)

现在假设给定Integer.class ,我想这样做:

final TypeLiteral<Converter<Integer>> typeLiteral = new TypeLiteral<Converter<Integer>>(){};
final Instance<Converter<Integer>> subInstance = converters.select(typeLiteral);
final Converter<Integer> converter = subInstance.get();

这很好用。

现在,在我的实际代码中,Integer.class被传入,作为满足声明为 Class<T> 的参数的值,所以我真正拥有的是:

final TypeLiteral<Converter<T>> typeLiteral = new TypeLiteral<Converter<T>>(){};
final Instance<Converter<T>> subInstance = converters.select(typeLiteral);
final Converter<T> converter = subInstance.get(); // this does not work

get()调用失败,堆栈跟踪以如下内容开头:

org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: Unsatisfied dependencies for type Converter<T> with qualifiers @Any 
    at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:105)

我必须做什么才能让这个选择成功?

我注意到一件事是堆栈报告 Converter<T>无法找到。这看起来很可疑:我本以为它会以 Converter<Integer> 的形式说话相反,由于 T “插槽”正在被“填充”Integer.class在运行时,尽管公平地说,我确实提供了一个 new TypeLiteral<Converter<T>>(){} , 不是 new TypeLiteral<Converter<Integer>>(){} .

无论如何,这一切告诉我 TypeLiteral<T>正在使用 T作为要查找的类型,而不是“填充” T 的实际值“插槽”,事实上,没有声明为 implements Converter<T> 的转换器, 只有一个转换器声明为 implements Converter<Integer> ,所以我担心我想在这里做的事情根本不可能。

最佳答案

创建 TypeLiteral捕获通用参数只有在编译时已知这些参数时才有效,因此 new TypeLiteral<Converter<Integer>>(){} .

如果类型参数在编译时未知,则 TypeLiteral 无法捕获参数信息,因为该信息已因类型删除而被删除。所以创建一个 new TypeLiteral<Converter<T>>(){}实际上只是创建了一个 new TypeLiteral<Converter<object>>(){} .

这意味着您的 select(typeLiteral)不会按预期工作,因为它将收到 Converter<object> 的类型文字.

关于java - 我必须使用什么类型的文字才能使 CDI 的 Instance::select 方法正常工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40227804/

相关文章:

jakarta-ee - CDI 在同一实例中调用拦截器注释方法

java - CDI 可以减少到 Java SE 吗?

transactions - CDI交易管理

java - CDI。如何检查bean是否实例化?

jpa - CDI 中 @Transactional 有哪些限制?

java - 如何打开文件并查看它

java - 为什么 Java 类加载在 Linux 上失败,但在 Windows 上成功?

java - java中的curl命令

java - 查明我的单元格是否属于一组合并单元格的一部分以及该组的大小

Java 框架 - 使用屏幕抓取来划分异构服务器环境