My understanding of Guice is that:
@Inject public class Widget(Dep one, Dep two)
) implies that Guice will always inject that constructor every time it is invoked through an Injector
; and@Inject public void setDepOne(Dep one)
) implies that Guice will always inject that method whenever it is called, so long as the Widget
object was created using the Guice Injector
Are these two assumptions correct? If not, please clarify!
So what I'm hung up on is: what are the implications of field-level injection?
@Inject private Dep one;
Does this mean that Guice will always inject the property when the object is created through the Guice injector? In that case I would imagine it conflicts with constructor-level injection.
For instance, does the following cause a conflict/error:
public class Widget {
@Inject private Dep one;
private Dep two;
// Dep one already injected as a field!
@Inject public Widget(Dep one, Dep two) {
// ...
}
}
Thanks in advance!
Guice will always inject all fields, methods, and any single constructor annotated with @Inject
. Keep in mind the constructor always gets injected first, so your annotated field will actually overwrite that injection. Take this modified example:
class Widget {
@Inject
private Dep one;
@Inject
public Widget(Dep one) {
this.one = one;
System.out.println(one);
}
public void printDependency() {
System.out.println(one);
}
}
class Dep {}
public class MyMain {
public static void main(String[] args) {
Injector i = Guice.createInjector();
i.getInstance(Widget.class).printDependency();
}
}
When run, this will produce something like this:
com.example.Dep@63238bd2
com.example.Dep@69198891
Clearly two different objects. The first line is the constructor; the second is the field injection.
I have not often found a use for field injection, except to reduce verbosity when writing Guice code samples. In production code it's unwise because it makes code difficult to test.