简体   繁体   English

Wildfly 8和通过提供者方法进行的焊缝CDI注入不会注入依赖项

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

I have an interface and an implementation of it like so; 我有一个接口及其实现。

interface MyInterface {
  public void doSomething();
}


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

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

Since I want to be able to change my databse via config file I use a provider method to generate the implementation 由于我希望能够通过配置文件更改数据库,因此我使用了提供程序方法来生成实现

@Singleton
public class MyApiProvider {

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

The thing is that when the MyImpl class is produced via the getMyApi method the "@Inject DB db;" 问题是,当通过getMyApi方法生成MyImpl类时,“ @ Inject DB db;” in the MyImpl class is null. 在MyImpl类中为null。

So what I want to do is just to be able to configure which implementation to use at runtime. 因此,我要做的就是能够配置要在运行时使用的实现。

EDIT: When I remove the @Alternative and remove the provider class/method everything is working as expected .. 编辑:当我删除@Alternative并删除提供程序类/方法时,一切都按预期工作..

EDIT 2: I would like to tell my webapp from a config file which implementation class of the MyInterface I want to use today. 编辑2:我想从配置文件中告诉我的webapp我今天要使用MyInterface的哪个实现类。 Tomorrow maybe I want another implementation and I do not want to recompile the whole project. 明天也许我想要另一个实现,而又不想重新编译整个项目。

This is happening because you are creating the MyImpl class rather than letting the CDI implementation do it. 之所以发生这种情况,是因为正在创建MyImpl类,而不是让CDI实现来实现。

You only get injection (and other annotation processing) when CDI is controlling the object life-cycle. 只有在CDI控制对象生命周期时,您才能进行注入(和其他注释处理)。

It's possible that what you're looking for is @Qualifier . 您可能正在寻找的是@Qualifier

Specific @Alternative s can be specified in the beans.xml file. 可以在beans.xml文件中指定特定的@Alternative

Alternatively, you might try something like: 或者,您可以尝试以下操作:

@ApplicationScoped
public class Configuration {

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

}

public class SomeClient {

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

    ...

}

You can use a producer method that chooses the concrete implementation based on a property/parameter: 您可以使用基于属性/参数选择具体实现的生产者方法:

@Produces
public MyInterface myInterface(MyImplA a, MyImplB b) {
   return (propertyValueA) ? a : b;
}

since instances a and b are required by the producer method, they will be created by the container and thus use injection. 由于生产者方法需要实例a和b,因此它们将由容器创建并因此使用注入。

This is a quick and simplified approach, if you need more variation or instance creation is expensive, you should use the CDI BeanManager to get and select the beans you want to return instead. 这是一种快速且简化的方法,如果您需要更多的变体或实例创建非常昂贵,则应使用CDI BeanManager来获取并选择要返回的Bean。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM