java - 通用 CDI 生产者方法未按预期工作

标签 java jakarta-ee cdi

我有一个 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)点stringValueintegerValue 只能接收一个有java.lang.Stringjava.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/

相关文章:

java - 标记 CSV 行转义双引号

java - Hibernate - 锁问题

java - 在后台运行 JAVA 中的 BASH 命令

java - JSF ApplicationScoped Bean 在 ServletContextListener 中使用 CDI 多次初始化

java - Undertow Websocket Bean 注入(inject) CDI 问题

java - 使用 Java 套接字发送字节数组

java - 应用于 AlertDialog 的样式无法正常工作

ajax - 如何将 @ConversationScoped 与 Ajax 请求一起使用?

database - 在hibernate中如何使用not in子句

java - SQL 只返回年份,不返回日期或月份