Suppose that I have two classes, first a class without any properties, fields or annotations:
public class B {}
And a class which gets B injected, like this:
public class A {
@Inject
private B b;
public B getB() {
return b;
}
}
Now class A is pretty useless until we use it, so there are two options:
If A gets injected, CDI manages it and is kind enough to inject B which has the implicit scope of @Dependent. Cool, just what I want.
However, if I manually construct A (let's say in a factory or a builder), CDI completely ignores my object and won't inject an object of type B.
Example I'm talking about when it doesn't work, here object a will always remain null:
public class Builder {
@Inject
private A a;
public static Builder ofTypeSomething() {
// do some magic here
return new Builder();
}
private Builder() {
// and some more here
}
}
Why doesn't this work?
Class A is a valid managed bean and has a valid scope, just like class B. Even if I add @Producer to the static method, it won't change anything (which is fine, cause the idea of the static method is to call it, not to inject Builder anywhere).
Dependency injection, while useful, is not magical. The way DI works is that when you ask the container for an instance of an object the container first constructs it (via new()
) and then sets the dependencies (how this happens depends on your framework).
If you construct the entity yourself then the container has no idea you've constructed the entity and can't set the dependencies of the entity.
If you want to use a factory then most frameworks have some way of configuring the entity so that the container knows to make a static factory method call and not call the constructor of the entity. However, you still have to obtain your entity from the container.
Edit: This site seems to demonstrate how to use a factory in CDI.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With