Search code examples
javaguice

Bootstrapping Guice injector


I have a scenario where I will need some objects injecting at the start like logging, but then other objects injected on demand. What I don't know is if in my console application, do I just call:

Guice.createInjector(....)

in my Main function and then when I need another object, the type that I need on demand, do I use a Provider to inject that same object again? I'm having a hard time figuring out the best way to use Guice's injector for this scenario.


Solution

  • In general, yes: Inject a Provider to get your objects later, and don't hold on to your Injector directly any longer than necessary.

    Ideally, your bootstrap should be just that: It should instantiate your Injector and get some sort of whole-application instance. This is particularly important because Guice is helpful for testing, so maximizing the part of the application subject to Guice is a good idea.

    public class YourApplication {
    
      public static void main(String[] args) {
        // Only three lines exist outside the object graph.
        Injector injector = Guice.createInjector(new YourModule1(), new YourModule2());
        YourApplication app = injector.getInstance(YourApplication.class);
        app.run();
      }
    
      @Inject Provider<YourDep1> depProvider1;
      @Inject YourDep2 dep2;
    
      public void run() {
        // Here you have access to every @Inject field.
      }
    }
    

    Here, bear in mind that the Injector you created is only kept on the stack. This is because you get everything you need from @Inject-annotated fields, methods, and constructors, including the Injector itself. As you suggested, you can use a Provider to get as many instances as you need, including zero instances if the object isn't necessary in that code path.