我有一个 CDI 生产者方法,它根据与此示例无关的某些条件创建不同类型的对象:
public class TestProducer {
@Produces @TestQualifier
public Object create(InjectionPoint ip) {
if(something) {
return "a String";
} else {
return Integer.valueOf(42);
}
}
但是在使用这个producer的时候,总是报错如下:
@Named("test")
public class TestComponent {
...
@Inject public void setA(@TestQualifier String stringValue) {
...
@Inject public void setB(@TestQualifier Integer integerValue) {
只有当生产者的create方法在方法签名中有预期的类型时才起作用:
public class TestProducer {
@Produces @SpringBean
public String create(InjectionPoint ip) {
现在 String get 已正确注入(inject),但我无法从生产者方法生成整数。但这正是我想要避免的,因为生产者本身应该是完全通用的。
我是做错了什么还是没有办法实现我想要的行为?
最佳答案
所有 CDI 文档都清楚地表明 CDI 执行 类型安全 依赖项注入(inject) - 这是 CDI 的一个高级属性。恕我直言,您正在尝试做的正是 CDI 试图避免的。您希望容器将 Object
转换为每种类型,而 CDI 不能那样工作。
注入(inject)点stringValue
和integerValue
只能接收一个有java.lang.String
和java.lang 的bean。 bean types 列表中的整数
分别。 java.lang.Object
不满足这个标准。
我有两个建议。首先,由于您有两个或更多不同类型的注入(inject)点,因此为这些类型创建两个或更多生产者方法:
public class TestProducer {
@Produces @TestQualifier
public String createString(InjectionPoint ip) {
if(something) {
return "a String";
} else {
// Some other value
}
}
@Produces @TestQualifier
public int createInt(InjectionPoint ip) {
if(something) {
return 42;
} else {
// Some other value
}
}
// ...
如果 something
条件只是检查注入(inject)点的类型(我敢打赌就是这种情况),它就会起作用。
但是,如果 something
条件确实使用注入(inject)点类型以外的其他标准来决定类型,我建议您自己做“肮脏的工作”:将返回值注入(inject)到Object
类型的注入(inject)点并手动进行转换:
@Named("test")
public class TestComponent {
...
@Inject public void setA(@TestQualifier Object value) {
String stringValue = (String) value;
...
@Inject public void setB(@TestQualifier Object value) {
int intValue = (Integer) value;
要点是,与其他一些 DI 框架不同,CDI 不针对 Java 类型系统工作——相反,它大量使用它。不要试图对抗它,而是使用 CDI 的这一方面对你有利:)
关于java - 通用 CDI 生产者方法未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4303514/