FooImpl
) cannot be directly injected unless
it is also explicitly bound (bind(FooImpl.class)
).
Tools can still retrieve bindings for implicit bindings (bindings created through a linked binding) if explicit bindings are required, however {@link Binding#getProvider} will fail.
By default, explicit bindings are not required.
If a parent injector requires explicit bindings, then all child injectors (and private modules within that injector) also require explicit bindings. If a parent does not require explicit bindings, a child injector or private module may optionally declare itself as requiring explicit bindings. If it does, the behavior is limited only to that child or any grandchildren. No siblings of the child will require explicit bindings.
If the parent did not require explicit bindings but the child does, it is possible that a linked binding in the child may add a JIT binding to the parent. The child will not be allowed to reference the target binding directly, but the parent and other children of the parent may be able to. @since 3.0]]>
bind(ServiceImpl.class);This statement does essentially nothing; it "binds the {@code ServiceImpl} class to itself" and does not change Guice's default behavior. You may still want to use this if you prefer your {@link Module} class to serve as an explicit manifest for the services it provides. Also, in rare cases, Guice may be unable to validate a binding at injector creation time unless it is given explicitly.
bind(Service.class).to(ServiceImpl.class);Specifies that a request for a {@code Service} instance with no binding annotations should be treated as if it were a request for a {@code ServiceImpl} instance. This overrides the function of any {@link ImplementedBy @ImplementedBy} or {@link ProvidedBy @ProvidedBy} annotations found on {@code Service}, since Guice will have already "moved on" to {@code ServiceImpl} before it reaches the point when it starts looking for these annotations.
bind(Service.class).toProvider(ServiceProvider.class);In this example, {@code ServiceProvider} must extend or implement {@code Provider
The {@link Provider} you use here does not have to be a "factory"; that is, a provider which always creates each instance it provides. However, this is generally a good practice to follow. You can then use Guice's concept of {@link Scope scopes} to guide when creation should happen -- "letting Guice work for you".
bind(Service.class).annotatedWith(Red.class).to(ServiceImpl.class);Like the previous example, but only applies to injection requests that use the binding annotation {@code @Red}. If your module also includes bindings for particular values of the {@code @Red} annotation (see below), then this binding will serve as a "catch-all" for any values of {@code @Red} that have no exact match in the bindings.
bind(ServiceImpl.class).in(Singleton.class); // or, alternatively bind(ServiceImpl.class).in(Scopes.SINGLETON);Either of these statements places the {@code ServiceImpl} class into singleton scope. Guice will create only one instance of {@code ServiceImpl} and will reuse it for all injection requests of this type. Note that it is still possible to bind another instance of {@code ServiceImpl} if the second binding is qualified by an annotation as in the previous example. Guice is not overly concerned with preventing you from creating multiple instances of your "singletons", only with enabling your application to share only one instance if that's all you tell Guice you need.
Note: a scope specified in this way overrides any scope that was specified with an annotation on the {@code ServiceImpl} class.
Besides {@link Singleton}/{@link Scopes#SINGLETON}, there are servlet-specific scopes available in {@code com.google.inject.servlet.ServletScopes}, and your Modules can contribute their own custom scopes for use here as well.
bind(new TypeLiteral<PaymentService<CreditCard>>() {}) .to(CreditCardPaymentService.class);This admittedly odd construct is the way to bind a parameterized type. It tells Guice how to honor an injection request for an element of type {@code PaymentService
bind(Service.class).toInstance(new ServiceImpl()); // or, alternatively bind(Service.class).toInstance(SomeLegacyRegistry.getService());In this example, your module itself, not Guice, takes responsibility for obtaining a {@code ServiceImpl} instance, then asks Guice to always use this single instance to fulfill all {@code Service} injection requests. When the {@link Injector} is created, it will automatically perform field and method injection for this instance, but any injectable constructor on {@code ServiceImpl} is simply ignored. Note that using this approach results in "eager loading" behavior that you can't control.
bindConstant().annotatedWith(ServerHost.class).to(args[0]);Sets up a constant binding. Constant injections must always be annotated. When a constant binding's value is a string, it is eligile for conversion to all primitive types, to {@link Enum#valueOf(Class, String) all enums}, and to {@link Class#forName class literals}. Conversions for other types can be configured using {@link #convertToTypes(Matcher, TypeConverter) convertToTypes()}.
{@literal @}Color("red") Color red; // A member variable (field) . . . red = MyModule.class.getDeclaredField("red").getAnnotation(Color.class); bind(Service.class).annotatedWith(red).to(RedService.class);If your binding annotation has parameters you can apply different bindings to different specific values of your annotation. Getting your hands on the right instance of the annotation is a bit of a pain -- one approach, shown above, is to apply a prototype annotation to a field in your module class, so that you can read this annotation instance and give it to Guice.
bind(Service.class) .annotatedWith(Names.named("blue")) .to(BlueService.class);Differentiating by names is a common enough use case that we provided a standard annotation, {@link com.google.inject.name.Named @Named}. Because of Guice's library support, binding by name is quite easier than in the arbitrary binding annotation case we just saw. However, remember that these names will live in a single flat namespace with all the other names used in your application.
ConstructorIn this example, we directly tell Guice which constructor to use in a concrete class implementation. It means that we do not need to place {@literal @}Inject on any of the constructors and that Guice treats the provided constructor as though it were annotated so. It is useful for cases where you cannot modify existing classes and is a bit simpler than using a {@link Provider}.loneCtor = getLoneCtorFromServiceImplViaReflection(); bind(ServiceImpl.class) .toConstructor(loneCtor);
The above list of examples is far from exhaustive. If you can think of how the concepts of one example might coexist with the concepts from another, you can most likely weave the two together. If the two concepts make no sense with each other, you most likely won't be able to do it. In a few cases Guice will let something bogus slip by, and will then inform you of the problems at runtime, as soon as you try to create your Injector.
The other methods of Binder such as {@link #bindScope}, {@link #bindInterceptor}, {@link #install}, {@link #requestStaticInjection}, {@link #addError} and {@link #currentStage} are not part of the Binding EDSL; you can learn how to use these in the usual way, from the method documentation. @author crazybob@google.com (Bob Lee) @author jessewilson@google.com (Jesse Wilson) @author kevinb@google.com (Kevin Bourrillion)]]>
bind(Service.class).annotatedWith(Red.class).to(ServiceImpl.class); bindConstant().annotatedWith(ServerHost.class).to(args[0]);
They exist on both modules and on injectors, and their behaviour is different for each:
public class FooApplication { public static void main(String[] args) { Injector injector = Guice.createInjector( new ModuleA(), new ModuleB(), . . . new FooApplicationFlagsModule(args) ); // Now just bootstrap the application and you're done FooStarter starter = injector.getInstance(FooStarter.class); starter.runApplication(); } }]]>
The returned map does not include bindings inherited from a {@link #getParent() parent injector}, should one exist. The returned map is guaranteed to iterate (for example, with its {@link Map#entrySet()} iterator) in the order of insertion. In other words, the order in which bindings appear in user Modules.
This method is part of the Guice SPI and is intended for use by tools and extensions.]]>
The returned map does not include bindings inherited from a {@link #getParent() parent injector}, should one exist.
This method is part of the Guice SPI and is intended for use by tools and extensions. @since 3.0]]>
No key may be bound by both an injector and one of its ancestors. This includes just-in-time bindings. The lone exception is the key for {@code Injector.class}, which is bound by each injector to itself. @since 2.0]]>
No key may be bound by both an injector and one of its ancestors. This includes just-in-time bindings. The lone exception is the key for {@code Injector.class}, which is bound by each injector to itself. @since 2.0]]>
An injector can also {@link #injectMembers(Object) inject the dependencies} of already-constructed instances. This can be used to interoperate with objects created by other frameworks or services.
Injectors can be {@link #createChildInjector(Iterable) hierarchical}. Child injectors inherit the configuration of their parent injectors, but the converse does not hold.
The injector's {@link #getBindings() internal bindings} are available for introspection. This enables tools and extensions to operate on an injector reflectively. @author crazybob@google.com (Bob Lee) @author jessewilson@google.com (Jesse Wilson)]]>
Example usage for a binding of type {@code Foo} annotated with {@code @Bar}:
{@code new Key
Example usage for a binding of type {@code Foo} annotated with {@code @Bar}:
{@code new Key
Example usage for a binding of type {@code Foo}:
{@code new Key
{@literal @}Inject public void setService({@literal @}Transactional Service service) { ... }
{@code Key} supports generic types via subclassing just like {@link TypeLiteral}.
Keys do not differentiate between primitive types (int, char, etc.) and their correpsonding wrapper types (Integer, Character, etc.). Primitive types will be replaced with their wrapper types when keys are created. @author crazybob@google.com (Bob Lee)]]>
In addition to the bindings configured via {@link #configure}, bindings will be created for all methods annotated with {@literal @}{@link Provides}. Use scope and binding annotations on these methods to configure the bindings.]]>
Guice EDSL bindings can be exposed with {@link #expose(Class) expose()}. {@literal @}{@link com.google.inject.Provides Provides} bindings can be exposed with the {@literal @}{@link Exposed} annotation:
public class FooBarBazModule extends PrivateModule { protected void configure() { bind(Foo.class).to(RealFoo.class); expose(Foo.class); install(new TransactionalBarModule()); expose(Bar.class).annotatedWith(Transactional.class); bind(SomeImplementationDetail.class); install(new MoreImplementationDetailsModule()); } {@literal @}Provides {@literal @}Exposed public Baz provideBaz() { return new SuperBaz(); } }
Private modules are implemented using {@link Injector#createChildInjector(Module[]) parent injectors}. When it can satisfy their dependencies, just-in-time bindings will be created in the root environment. Such bindings are shared among all environments in the tree.
The scope of a binding is constrained to its environment. A singleton bound in a private module will be unique to its environment. But a binding for the same type in a different private module will yield a different instance.
A shared binding that injects the {@code Injector} gets the root injector, which only has access to bindings in the root environment. An explicit binding that injects the {@code Injector} gets access to all bindings in the child environment.
To promote a just-in-time binding to an explicit binding, bind it:
bind(FooImpl.class);@author jessewilson@google.com (Jesse Wilson) @since 2.0]]>
An example of a scope is {@link Scopes#SINGLETON}. @author crazybob@google.com (Bob Lee)]]>
{@code TypeLiteral Along with modeling generic types, this class can resolve type parameters.
For example, to figure out what type {@code keySet()} returns on a {@code
Map> list = new TypeLiteral
>() {};}
{@code
TypeLiteral
@author crazybob@google.com (Bob Lee)
@author jessewilson@google.com (Jesse Wilson)]]>
Obsolete Usage: When used in tandem with {@link FactoryProvider}, constructors annotated with {@code @AssistedInject} trigger a "backwards compatibility mode". The assisted parameters must exactly match one corresponding factory method within the factory interface and all must be in the same order as listed in the factory. In this backwards compatable mode, constructors annotated with AssistedInject are not created by Guice and thus receive none of the benefits.
Constructor parameters must be either supplied by the factory interface and marked with
@Assisted
, or they must be injectable.
@author jmourits@google.com (Jerome Mourits)
@author jessewilson@google.com (Jesse Wilson)]]>
public interface PaymentFactory { Payment create(Date startDate, Money amount); }You can name your factory methods whatever you like, such as create, createPayment or newPayment.
public class RealPayment implements Payment { {@literal @}Inject public RealPayment( CreditService creditService, AuthService authService, {@literal @}Assisted Date startDate, {@literal @}Assisted Money amount) { ... } }
public interface PaymentFactory { Payment create(Date startDate, Money amount); Payment createWithoutDate(Money amount); } public class RealPayment implements Payment { {@literal @}AssistedInject public RealPayment( CreditService creditService, AuthService authService, {@literal @}Assisted Date startDate, {@literal @}Assisted Money amount) { ... } {@literal @}AssistedInject public RealPayment( CreditService creditService, AuthService authService, {@literal @}Assisted Money amount) { ... } }
install(new FactoryModuleBuilder() .implement(Payment.class, RealPayment.class) .build(PaymentFactory.class);As a side-effect of this binding, Guice will inject the factory to initialize it for use. The factory cannot be used until the injector has been initialized.
.implement
.
public interface OrderFactory { Payment create(Date startDate, Money amount); Shipment create(Customer customer, Item item); Receipt create(Payment payment, Shipment shipment); } [...] install(new FactoryModuleBuilder() .implement(Payment.class, RealPayment.class) // excluding .implement for Shipment means the implementation class // will be 'Shipment' itself, which is legal if it's not an interface. .implement(Receipt.class, RealReceipt.class) .build(OrderFactory.class);
public class PaymentAction { {@literal @}Inject private PaymentFactory paymentFactory; public void doPayment(Money amount) { Payment payment = paymentFactory.create(new Date(), amount); payment.apply(); } }
public interface PaymentFactory { Payment create( {@literal @}Assisted("startDate") Date startDate, {@literal @}Assisted("dueDate") Date dueDate, Money amount); }...and to the concrete type's constructor parameters:
public class RealPayment implements Payment { {@literal @}Inject public RealPayment( CreditService creditService, AuthService authService, {@literal @}Assisted("startDate") Date startDate, {@literal @}Assisted("dueDate") Date dueDate, {@literal @}Assisted Money amount) { ... } }
public interface FruitFactory { Apple getApple(Color color); } ... protected void configure() { install(new FactoryModuleBuilder().build(FruitFactory.class)); }Note that any type returned by the factory in this manner needs to be an implementation class. To return two different implementations for the same interface from your factory, use binding annotations on your return types:
interface CarFactory { {@literal @}Named("fast") Car getFastCar(Color color); {@literal @}Named("clean") Car getCleanCar(Color color); } ... protected void configure() { install(new FactoryModuleBuilder() .implement(Car.class, Names.named("fast"), Porsche.class) .implement(Car.class, Names.named("clean"), Prius.class) .build(CarFactory.class)); }
Provides a factory that combines the caller's arguments with injector-supplied values to construct objects.
public interface PaymentFactory { Payment create(Date startDate, Money amount); }You can name your factory methods whatever you like, such as create, createPayment or newPayment.
public class RealPayment implements Payment { {@literal @}Inject public RealPayment( CreditService creditService, AuthService authService, {@literal @}Assisted Date startDate, {@literal @}Assisted Money amount) { ... } }Any parameter that permits a null value should also be annotated {@code @Nullable}.
bind(PaymentFactory.class).toProvider( FactoryProvider.newFactory(PaymentFactory.class, RealPayment.class));As a side-effect of this binding, Guice will inject the factory to initialize it for use. The factory cannot be used until the injector has been initialized.
public class PaymentAction { {@literal @}Inject private PaymentFactory paymentFactory; public void doPayment(Money amount) { Payment payment = paymentFactory.create(new Date(), amount); payment.apply(); } }
public interface PaymentFactory { Payment create( {@literal @}Assisted("startDate") Date startDate, {@literal @}Assisted("dueDate") Date dueDate, Money amount); }...and to the concrete type's constructor parameters:
public class RealPayment implements Payment { {@literal @}Inject public RealPayment( CreditService creditService, AuthService authService, {@literal @}Assisted("startDate") Date startDate, {@literal @}Assisted("dueDate") Date dueDate, {@literal @}Assisted Money amount) { ... } }
Instead of matching factory method arguments to constructor parameters using their names, the parameters are matched by their order. The first factory method argument is used for the first {@literal @}Assisted constructor parameter, etc.. Annotation names have no effect.
Returned values are not created by Guice. These types are not eligible for
method interception. They do receive post-construction member injection.
@param
By default, this will graph the entire {@link Injector}. Use {@link #rootedAt(Class...)} or {@link #rootedAt(Key...)} to specify an initial set of {@link Class}es or {@link Key}s to use, and this will graph their transitive bindings and dependencies. @author phopkins@gmail.com (Pete Hopkins)]]>
In addition to the {@code Map
When multiple modules contribute elements to the map, this configuration
option impacts all of them.
@return this map binder
@since 3.0]]>
Scoping elements independently is supported. Use the {@code in} method to specify a binding scope.]]>
public class SnacksModule extends AbstractModule {
protected void configure() {
MapBinder<String, Snack> mapbinder
= MapBinder.newMapBinder(binder(), String.class, Snack.class);
mapbinder.addBinding("twix").toInstance(new Twix());
mapbinder.addBinding("snickers").toProvider(SnickersProvider.class);
mapbinder.addBinding("skittles").to(Skittles.class);
}
}
With this binding, a {@link Map}{@code In addition to binding {@code Map Contributing mapbindings from different modules is supported. For example,
it is okay to have both {@code CandyModule} and {@code ChipsModule} both
create their own {@code MapBinder The map's iteration order is consistent with the binding order. This is
convenient when multiple elements are contributed by the same module because
that module can order its bindings appropriately. Avoid relying on the
iteration order of elements contributed by different modules, since there is
no equivalent mechanism to order modules.
The map is unmodifiable. Elements can only be added to the map by
configuring the MapBinder. Elements can never be removed from the map.
Values are resolved at map injection time. If a value is bound to a
provider, that provider's get method will be called each time the map is
injected (unless the binding is also scoped, or a map of providers is injected).
Annotations are used to create different maps of the same key/value
type. Each distinct annotation gets its own independent map.
Keys must be distinct. If the same key is bound more than
once, map injection will fail. However, use {@link #permitDuplicates()} in
order to allow duplicate keys; extra bindings to {@code Map Keys must be non-null. {@code addBinding(null)} will
throw an unchecked exception.
Values must be non-null to use map injection. If any
value is null, map injection will fail (although injecting a map of providers
will not).
@author dpb@google.com (David P. Baker)]]>
class SnackMachine {
{@literal @}Inject
public SnackMachine(Map<String, Snack> snacks) { ... }
}
class SnackMachine {
{@literal @}Inject
public SnackMachine(Map<String, Provider<Snack>> snackProviders) { ... }
}
Map<String, Snack>
, then this will always return a
TypeLiteral<String>
.]]>
Map<String, Snack>
, then this will always return a
TypeLiteral<Snack>
.]]>
Map<String, Snack>
, then this will always return a list of type
List<Map.Entry<String, Binding<Snack>>>
.]]>
MapBinderBinding<Map<String, Snack>>
@since 3.0
@author sameb@google.com (Sam Berlin)]]>
Scoping elements independently is supported. Use the {@code in} method to specify a binding scope.]]>
public class SnacksModule extends AbstractModule {
protected void configure() {
Multibinder<Snack> multibinder
= Multibinder.newSetBinder(binder(), Snack.class);
multibinder.addBinding().toInstance(new Twix());
multibinder.addBinding().toProvider(SnickersProvider.class);
multibinder.addBinding().to(Skittles.class);
}
}
With this binding, a {@link Set}{@code Contributing multibindings from different modules is supported. For
example, it is okay to have both {@code CandyModule} and {@code ChipsModule}
to both create their own {@code Multibinder The set's iteration order is consistent with the binding order. This is
convenient when multiple elements are contributed by the same module because
that module can order its bindings appropriately. Avoid relying on the
iteration order of elements contributed by different modules, since there is
no equivalent mechanism to order modules.
The set is unmodifiable. Elements can only be added to the set by
configuring the multibinder. Elements can never be removed from the set.
Elements are resolved at set injection time. If an element is bound to a
provider, that provider's get method will be called each time the set is
injected (unless the binding is also scoped).
Annotations are be used to create different sets of the same element
type. Each distinct annotation gets its own independent collection of
elements.
Elements must be distinct. If multiple bound elements
have the same value, set injection will fail.
Elements must be non-null. If any set element is null,
set injection will fail.
@author jessewilson@google.com (Jesse Wilson)]]>
class SnackMachine {
{@literal @}Inject
public SnackMachine(Set<Snack> snacks) { ... }
}
Set<String>
, then this will always return a
TypeLiteral<String>
.]]>
Set<String>
, then this will always return a list of type
List<Binding<String>>
.]]>
MultibinderBinding<Set<Boolean>>
@since 3.0
@author sameb@google.com (Sam Berlin)]]>
Example configuration:
{@code public class MyModule extends ServletModule { public void configureServlets() { filter("/*").through(PersistFilter.class); serve("/index.html").with(MyHtmlServlet.class); // Etc. } } }
This filter is thread safe and allows you to create injectors concurrently and deploy multiple guice-persist modules within the same injector, or even multiple injectors with persist modules withing the same JVM or web app.
This filter requires the Guice Servlet extension. @author Dhanji R. Prasanna (dhanji@gmail.com)]]>
If the method throws an exception, the transaction will be rolled back unless you have specifically requested not to in the {@link #ignore()} clause.
Similarly, the set of exceptions that will trigger a rollback can be defined in the {@link #rollbackOn()} clause. By default, only unchecked exceptions trigger a rollback. @author Dhanji R. Prasanna (dhanji@gmail.com)]]>
<filter> <filter-name>guiceFilter</filter-name> <filter-class>com.google.inject.servlet.GuiceFilter</filter-class> </filter> <filter-mapping> <filter-name>guiceFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>This filter must appear before every filter that makes use of Guice injection or servlet scopes functionality. Typically, you will only register this filter in web.xml and register any other filters (and servlets) using a {@link ServletModule}. @author crazybob@google.com (Bob Lee) @author dhanji@gmail.com (Dhanji R. Prasanna)]]>
Part of the EDSL builder language for configuring servlets and filters with guice-servlet. Think of this as an in-code replacement for web.xml. Filters and servlets are configured here using simple java method calls. Here is a typical example of registering a filter when creating your Guice injector:
Guice.createInjector(..., new ServletModule() { {@literal @}Override protected void configureServlets() { serve("*.html").with(MyServlet.class) } }This registers a servlet (subclass of {@code HttpServlet}) called {@code MyServlet} to service any web pages ending in {@code .html}. You can also use a path-style syntax to register servlets:
serve("/my/*").with(MyServlet.class)Every servlet (or filter) is required to be a singleton. If you cannot annotate the class directly, you should add a separate {@code bind(..).in(Singleton.class)} rule elsewhere in your module. Mapping a servlet that is bound under any other scope is an error.
Guice.createInjector(..., new ServletModule() { {@literal @}Override protected void configureServlets() { filter("/*").through(MyFilter.class); filter("*.css").through(MyCssFilter.class); filter("*.jpg").through(new MyJpgFilter()); // etc.. serve("*.html").with(MyServlet.class); serve("/my/*").with(MyServlet.class); serve("*.jpg").with(new MyServlet()); // etc.. } }This will traverse down the list of rules in lexical order. For example, a url "{@code /my/file.js}" (after it runs through the matching filters) will first be compared against the servlet mapping:
serve("*.html").with(MyServlet.class);And failing that, it will descend to the next servlet mapping:
serve("/my/*").with(MyServlet.class);Since this rule matches, Guice Servlet will dispatch to {@code MyServlet}. These two mapping rules can also be written in more compact form using varargs syntax:
serve("*.html", "/my/*").with(MyServlet.class);This way you can map several URI patterns to the same servlet. A similar syntax is also available for filter mappings.
serveRegex("(.)*ajax(.)*").with(MyAjaxServlet.class)This will map any URI containing the text "ajax" in it to {@code MyAjaxServlet}. Such as:
Map<String, String> params = new HashMap<String, String>(); params.put("name", "Dhanji"); params.put("site", "google.com"); ... serve("/*").with(MyServlet.class, params)
... filter("/*").through(Key.get(Filter.class, Fave.class));Where {@code Filter.class} refers to the Servlet API interface and {@code Fave.class} is a custom binding annotation. Elsewhere (in one of your own modules) you can bind this filter's implementation:
bind(Filter.class).annotatedWith(Fave.class).to(MyFilterImpl.class);See {@link com.google.inject.Binder} for more information on binding syntax.
Guice Servlet allows you to register several instances of {@code ServletModule} to your injector. The order in which these modules are installed determines the dispatch order of filters and the precedence order of servlets. For example, if you had two servlet modules, {@code RpcModule} and {@code WebServiceModule} and they each contained a filter that mapped to the same URI pattern, {@code "/*"}:
In {@code RpcModule}:
filter("/*").through(RpcFilter.class);In {@code WebServiceModule}:
filter("/*").through(WebServiceFilter.class);Then the order in which these filters are dispatched is determined by the order in which the modules are installed:
install(new WebServiceModule()); install(new RpcModule());In the case shown above {@code WebServiceFilter} will run first. @since 2.0]]>
The elements of an injector can be inspected and exercised. Use {@link com.google.inject.Injector#getBindings Injector.getBindings()} to reflect on Guice injectors. @author jessewilson@google.com (Jesse Wilson) @author crazybob@google.com (Bob Lee) @since 2.0]]>
Due to issues with generics, the type parameters of this method do not relate to the type of the provider. In practice, the 'B' type will always be a supertype of 'T'.]]>
<V, B> V acceptExtensionVisitor(BindingTargetVisitor<B, V> visitor, ProviderInstanceBinding<? extends B> binding) { if(visitor instanceof MyCustomExtensionVisitor) { return ((MyCustomExtensionVisitor<B, V>)visitor).visitCustomExtension(customProperties, binding); } else { return visitor.visit(binding); } }'MyCustomExtensionVisitor' in the example above would be an interface the extension provides that users can implement in order to be notified of custom extension information. These visitor interfaces must extend from BindingTargetVisitor. @since 3.0 @author sameb@google.com (Sam Berlin)]]>
public interface RemoteProvider<T> extends CheckedProvider<T> { T get() throws CustomExceptionOne, CustomExceptionTwo; }
When this type is bound using {@link ThrowingProviderBinder}, the value returned or exception thrown by {@link #get} will be scoped. As a consequence, {@link #get} will invoked at most once within each scope. @since 3.0]]>
public interface RemoteProvider<T> extends ThrowingProvider<T, RemoteException> { }
When this type is bound using {@link ThrowingProviderBinder}, the value returned or exception thrown by {@link #get} will be scoped. As a consequence, {@link #get} will invoked at most once within each scope. @author jmourits@google.com (Jerome Mourits) @author jessewilson@google.com (Jesse Wilson) @deprecated use {@link CheckedProvider} instead.]]>
You can use a fluent API and custom providers:
ThrowingProviderBinder.create(binder())
.bind(RemoteProvider.class, Customer.class)
.to(RemoteCustomerProvider.class)
.in(RequestScope.class);
or, you can use throwing provider methods:
class MyModule extends AbstractModule {
configure() {
ThrowingProviderBinder.install(this, binder());
}
{@literal @}CheckedProvides(RemoteProvider.class)
{@literal @}RequestScope
Customer provideCustomer(FlakyCustomerCreator creator) throws RemoteException {
return creator.getCustomerOrThrow();
}
}
@author jmourits@google.com (Jerome Mourits)
@author jessewilson@google.com (Jesse Wilson)]]>
Prefer to write smaller modules that can be reused and tested without overrides. @param modules the modules whose bindings are open to be overridden]]>
Prefer to write smaller modules that can be reused and tested without overrides. @param modules the modules whose bindings are open to be overridden]]>