Wildfly 8 和 weld CDI inject via provider 方法不注入依赖

Wildfly 8 and weld CDI inject via provider method does not inject dependecies

我有一个接口和它的实现;

interface MyInterface {
  public void doSomething();
}


@Alternative
class MyImpl implements MyInterface {
  @Inject DB db;

  public void doSomething() {
    // db.select ....
  }
}

因为我希望能够通过配置文件更改我的数据库,所以我使用提供程序方法来生成实现

@Singleton
public class MyApiProvider {

    @Produces
    public MyInterface getMyApi() {
        return new MyImpl();
    }
}

问题是,当 MyImpl class 通过 getMyApi 方法生成时,“@Inject DB db;”在 MyImpl 中 class 为空。

所以我想做的只是能够配置在运行时使用哪个实现。

编辑: 当我删除 @Alternative 并删除提供程序时 class/method 一切都按预期工作..

编辑 2: 我想从配置文件中告诉我的 webapp 我今天想使用 MyInterface 的哪个实现 class。明天也许我想要另一个实现,我不想重新编译整个项目。

这是因为 正在创建 MyImpl class 而不是让 CDI 实现来完成它。

您仅在 CDI 控制对象生命周期时进行注入(和其他注释处理)。

您要找的可能是@Qualifier

可以在 beans.xml 文件中指定特定的 @Alternative

或者,您可以尝试以下方法:

@ApplicationScoped
public class Configuration {

     public String getMyInterfaceImpl() {
         // property file loading logic
     }

}

public class SomeClient {

    @Inject @Named("#{configuration.myInterfaceImpl}")
    private MyInterface myInterface;

    ...

}

您可以使用基于 property/parameter:

选择具体实现的生产者方法
@Produces
public MyInterface myInterface(MyImplA a, MyImplB b) {
   return (propertyValueA) ? a : b;
}

由于生产者方法需要实例a和b,它们将由容器创建,因此使用注入。

这是一种快速且简化的方法,如果您需要更多变化或实例创建成本高昂,您应该使用 CDI BeanManager 来获取 select 您想要 return 的 bean。