问题
I'm using WELD SE on a standalone java project which seemed to work fine till I started using producers.
The producer method works - the container uses it, but never injects the inner pdependencies of the produced bean. When I remove the producer, it works normally. I can't find the cause even after a long search on the spec and on Google.
Example of a Producer:
@ApplicationScoped
public class LaminaValidadorProducer {
private static final String XSD_PATH = getConfig("processador.xsd.path");
private static final Map<VersaoLamina,String> XSD_PER_VERSION = new HashMap<>();
static {
XSD_PER_VERSION.put(VersaoLamina.V1, getConfig("processador.lamina.xsd.file"));
XSD_PER_VERSION.put(VersaoLamina.V2, getConfig("processador.laminav2.xsd.file"));
}
@Produces
public LaminaValidador buildValidador() {
return new LaminaValidador(XSD_PATH, XSD_PER_VERSION);
}
}
LaminaValidador is injected normally, but its INNER attributes (marked with @Inject) are not being injected. THe project has a beans.xml with bean-discovery-mode="all".
Any clues on what's happening?
回答1:
This is not only a matter of SE and it is in fact a desired/expected behaviour of CDI.
The reason behind this is that normally, if you do not have producers, CDI creates the bean classes for you (by calling no-args constructor, or one with injections) and subsequently resolves the injection points within the bean (and does some other things, see spec). E.g. you leave the lifecycle management to CDI container.
On the other hand, using a producer is usually a way to create a bean out of a class where:
- you cannot control lifecycle youself, e.g. EntityManager
- you intergrate with other frameworks and they have complex initialization
- you need to do some checks for external config before calling certain constructor
- or you maybe want a bean for a primitive type (int)
- and many many more use cases
Now this means you are responsible for the creation of the bean. And that includes any fields within. Container just takes the producer as a way to create a full-blown bean and assumes you took care or what the initialization required.
Now, from your question I judge you need the injection point resolution inside. There is no easy way, if any, to "enforce" the resolution manually due to static nature of CDI (and other, more complex reasons). Hence I would propose to use a different approach and leverage constructor injection or maybe initializer methods? If you provide more information, I might be able to help.
来源:https://stackoverflow.com/questions/40225429/cdi-weld-se-not-injecting-inner-dependencies-when-using-producer-method