Skip to content

JustInTimeBindings

Googler edited this page Aug 6, 2020 · 12 revisions

Just-in-time Bindings

Bindings that are created automatically by Guice

When the injector needs an instance of a type, it needs a binding. The bindings in a modules are called explicit bindings, and the injector uses them whenever they're available. If a type is needed but there isn't an explicit binding, the injector will attempt to create a Just-In-Time binding. These are also known as JIT bindings or implicit bindings.

@Inject Constructors

Guice can create bindings for concrete types by using the type's injectable constructor. This is either a non-private, no-arguments constructor, or a constructor with the @Inject annotation:

public class PayPalCreditCardProcessor implements CreditCardProcessor {
  private final String apiKey;

  @Inject
  public PayPalCreditCardProcessor(@PaypalApiKey String apiKey) {
    this.apiKey = apiKey;
  }

Guice will not construct nested classes unless they have the static modifier. Inner classes have an implicit reference to their enclosing class that cannot be injected.

@ImplementedBy

Annotate types tell the injector what their default implementation type is. The @ImplementedBy annotation acts like a linked binding, specifying the subtype to use when building a type.

@ImplementedBy(PayPalCreditCardProcessor.class)
public interface CreditCardProcessor {
  ChargeResult charge(String amount, CreditCard creditCard)
      throws UnreachableException;
}

The above annotation is equivalent to the following bind() statement:

    bind(CreditCardProcessor.class).to(PayPalCreditCardProcessor.class);

If a type is in both a bind() statement (as the first argument) and has the @ImplementedBy annotation, the bind() statement is used. The annotation suggests a default implementation that can be overridden with a binding. Use @ImplementedBy carefully; it adds a compile-time dependency from the interface to its implementation.

@ProvidedBy

@ProvidedBy tells the injector about a Provider class that produces instances:

@ProvidedBy(DatabaseTransactionLogProvider.class)
public interface TransactionLog {
  void logConnectException(UnreachableException e);
  void logChargeResult(ChargeResult result);
}

The annotation is equivalent to a toProvider() binding:

    bind(TransactionLog.class)
        .toProvider(DatabaseTransactionLogProvider.class);

Like @ImplementedBy, if the type is annotated and used in a bind() statement, the bind() statement will be used.

Enforce Explicit Bindings

New in Guice 3.0

To disable implicit bindings, you can use the requireExplicitBindings API:

final class ExplicitBindingModule extends AbstractModule {
  @Override
  protected void configue() {
    binder().requireExplicitBindings();
  }
}

Installing the above module will cause Guice to enforce that all bindings must be listed in a Module in order to be injected.

Clone this wiki locally