简体   繁体   中英

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;" in the MyImpl class is 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 ..

EDIT 2: I would like to tell my webapp from a config file which implementation class of the MyInterface I want to use today. 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.

You only get injection (and other annotation processing) when CDI is controlling the object life-cycle.

It's possible that what you're looking for is @Qualifier .

Specific @Alternative s can be specified in the beans.xml file.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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