-
Notifications
You must be signed in to change notification settings - Fork 1.7k
JustInTimeBindings
Bindings that are created automatically by Guice
When the injector needs an instance of a type, it needs a binding. The bindings in 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.
Guice can create bindings for concrete types by using the type's injectable constructor. Guice considers a constructor injectable if:
- (recommended) The constructor is explicitly annotated with
@Inject
(bothcom.google.inject.Inject
andjavax.inject.Inject
are supported). - or, the constructor takes zero arguments, and
- the constructor is non-private and defined in a non-private class (Guice supports private constructor only when it is defined in a private class, however, private constructors are not recommended because they can be slow in Guice due to the cost of reflection).
- the injector has not opted in to require explicit @Inject constructor, see explicit @Inject constructors section below.
Injectable constructor examples:
public final class Foo {
// An @Inject annotated constructor.
@Inject
Foo(Bar bar) {
...
}
}
public final class Bar {
// A no-arg non private constructor.
Bar() {}
private static class Baz {
// A private constructor to a private class is also usable by Guice, but
// this is not recommended since it can be slow.
private Baz() {}
}
}
A constructor is not injectable if:
- The constructor takes one or more arguments and is not annotated with
@Inject
. - There are more than one
@Inject
annotated constructors. - The constructor is defined in a non-static nested class. Inner classes have an implicit reference to their enclosing class that cannot be injected.
Non-injectable constructor examples:
public final class Foo {
// Not injectable because the construct takes an argument and there is no
// @Inject annotation.
Foo(Bar bar) {
...
}
}
public final class Bar {
// Not injectable because the constructor is private
private Bar() {}
class Baz {
// Not injectable because Baz is not a static inner class
Baz() {}
}
}
An application can opt-in to enforce that Guice only use @Inject
annotated
constructors by calling binder().requireAtInjectOnConstructors()
in a module
that is installed in the injector. When opted-in, Guice will only consider
@Inject
annotated constructors and if there is none then a
MISSING_CONSTRUCTOR
is reported.
TIP: Install Modules.requireAtInjectOnConstructorsModule()
to opt-in for
@Inject
on constructor requirement.
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
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.
New in Guice 3.0
To disable implicit bindings, you can use the requireExplicitBindings
API:
final class ExplicitBindingModule extends AbstractModule {
@Override
protected void configure() {
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.
-
User's Guide
-
Integration
-
Extensions
-
Internals
-
Releases
-
Community