Say we have the following code:
public interface Rock {
// Minerals are a concrete class; omitted for brevity
public Minerals getMinerals();
}
public class Granite implements Rock {
// @Inject #1 - field
private Minerals minerals;
// @Inject #2 - constructor
public Granite(Minerals mins) {
super();
setMinerals(mins);
}
public Minerals getMinerals() {
return minerals;
}
// @Inject #3 - setter
public void setMinerals(Minerals mins) {
minerals = mins
}
}
public class RockModule extends AbstractModule {
public void configure(Binder guiceBinder) {
Minerals m = new Minerals(true, 3, MineralEnum.Sedimentary);
guiceBinder.bind(Minerals.class).toInstance(m);
guiceBinder.bind(Rock.class).to(Granite.class);
}
}
public class TestInjections {
public static void main(String[] args) {
RockModule mod = new RockModule();
Injector injector = Guice.createInjector(mod);
Granite gran = injector.getInstance(Granite.class);
}
}
I have commented out the 3 @Inject annotations as they are the variables here – I’m wondering how Guice will behave in all 3 cases (field-, constructor- or setter-level injections).
- Will
Graniteinstances always be injected with theMineralsinstance configured in the module? How does the injection type (each of the 3) affect theGraniteinstances returned by the injector – or are they all the same? - What if I never explicitly bound
Mineralsin the module at all andMineralsdoesn’t have a public no-arg constructor defined? For all three injection scenarios, how does Guice instantiate aMineralsinstance to be returned for the requestedGraniteobject?
Mineralswill always be injected into theGranite, whichever injection technique you choose, but some injections are “cleaner” than others — for example, option 1 gives you less control over how the injection is done, and option 3 means your class can’t be immutable.Mineralsisn’t bound, lacks a public no-argument constructor, and lacks an@Injectconstructor, then Guice throws an exception, unless you use@Inject(optional = true).