Reputation: 599
I am trying to inject a dependency into a bean (Some/OtherImpl
), annotated with @Named
but the dependency (configurationService
) always gets resolved to null
(Resources#getConfiguratioService
is not called) when a new instance of that bean is created in the controller (MyCtrl) by using its producer method.
However if I try to inject ConfigurationService directly into the controller, the method Resources#getConfiguratioService
executes and creates new instance of the ConfigurationService
which gets injected into the controller.
This is how it looks like
public class Resources() {
@Produces
public ConfigurationService getConfigurationService() {
return new ConfigurationService(Constants.CONFIG);
}
}
public abstract class MyAbstractClass {
@Inject
private transient ConfigurationService configurationService; // getter+setter
}
@Named
public class SomeImpl extends MyAbstractClass implements Serializable {
// ...
}
@Named
public class OtherImpl extends MyAbstractClass implements Serializable {
// ...
}
@Named
@ViewScoped
public class MyCtrl {
@Inject
private SomeImpl someImpl;
@Produces
public SomeImpl getSomeImpl() {
return new SomeImpl(MyStringParam);
}
}
Can you please tell me what am I doing wrong here? Is there a way how to fix it? Every hint will be appreciated. Thx in advance!
Upvotes: 2
Views: 1419
Reputation: 6753
The problem here is that you are creating the instance of SomeImpl
'manually' using the new
keyword. In that case, you create/provide the object, no injection takes place, and you hand over this object to CDI. From there on, any injection point of type SomeImpl
and with default qualifiers will use your producer to create the bean. Producers are often a way to turn non-CDI objects into CDI bean but have the limitation that injection doesn't happen; note that this limitation is sometimes an actual advantage because some other framework might resolve injection or otherwise instantiate and change the instance and you just pass it over to CDI (example - integration with EJB).
As a solution, delete the producer and let CDI create the instance on its own. CDI will invoke a no-arg constructor (or a constructor with injectable params if present) to create the instance and then perform injection into this new object.
From there on, your code should work just as you expect it to.
In rare cases where you cannot let CDI managed the whole lifecycle and actually need to manually create instance and still inject into it, InjectionTargetFactory
is what you are looking for.It requires a but BeanManager.getInjectionTargetFactory()
is the starting point you need.
Upvotes: 3