All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.inject.Binder Maven / Gradle / Ivy

package com.google.inject;

import com.google.inject.binder.AnnotatedBindingBuilder;
import com.google.inject.binder.AnnotatedConstantBindingBuilder;
import com.google.inject.binder.LinkedBindingBuilder;
import com.google.inject.matcher.Matcher;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.Message;
import com.google.inject.spi.ModuleAnnotatedMethodScanner;
import com.google.inject.spi.ProvisionListener;
import com.google.inject.spi.TypeConverter;
import com.google.inject.spi.TypeListener;

import java.lang.annotation.Annotation;
import java.lang.reflect.Proxy;

/**
 * Collects configuration information (primarily bindings) which will be
 * used to create an {@link Injector}. Guice provides this object to your
 * application's {@link Module} implementors so they may each contribute
 * their own bindings and other registrations.
 *
 * 

The Guice Binding EDSL

* * Guice uses an embedded domain-specific language, or EDSL, to help you * create bindings simply and readably. This approach is great for overall * usability, but it does come with a small cost: it is difficult to * learn how to use the Binding EDSL by reading * method-level javadocs. Instead, you should consult the series of * examples below. To save space, these examples omit the opening * {@code binder}, just as you will if your module extends * {@link AbstractModule}. * *
 *     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}. This binding specifies that Guice should resolve * an unannotated injection request for {@code Service} by first resolving an * instance of {@code ServiceProvider} in the regular way, then calling * {@link Provider#get get()} on the resulting Provider instance to obtain the * {@code Service} instance. * *

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}. The class * {@code CreditCardPaymentService} must implement the * {@code PaymentService} interface. Guice cannot currently bind or * inject a generic type, such as {@code Set}; all type parameters must be * fully specified. * *
 *     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. * *
 *     Constructor<T> loneCtor = getLoneCtorFromServiceImplViaReflection();
 *     bind(ServiceImpl.class)
 *         .toConstructor(loneCtor);
* * In 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}. * *

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 #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. */ public interface Binder { /** * Binds a scope to an annotation. */ void bindScope(Class annotationType, Scope scope); /** * See the EDSL examples at {@link Binder}. */ LinkedBindingBuilder bind(Key key); /** * See the EDSL examples at {@link Binder}. */ AnnotatedBindingBuilder bind(TypeLiteral typeLiteral); /** * See the EDSL examples at {@link Binder}. */ AnnotatedBindingBuilder bind(Class type); /** * See the EDSL examples at {@link Binder}. */ AnnotatedConstantBindingBuilder bindConstant(); /** * Upon successful creation, the {@link Injector} will inject instance fields * and methods of the given object. * * @param type of instance * @param instance for which members will be injected */ void requestInjection(TypeLiteral type, T instance); /** * Upon successful creation, the {@link Injector} will inject instance fields * and methods of the given object. * * @param instance for which members will be injected */ void requestInjection(Object instance); /** * Upon successful creation, the {@link Injector} will inject static fields * and methods in the given classes. * * @param types for which static members will be injected */ void requestStaticInjection(Class... types); /** * Uses the given module to configure more bindings. */ void install(Module module); /** * Gets the current stage. */ Stage currentStage(); /** * Records an error message which will be presented to the user at a later * time. Unlike throwing an exception, this enable us to continue * configuring the Injector and discover more errors. Uses {@link * String#format(String, Object[])} to insert the arguments into the * message. */ void addError(String message, Object... arguments); /** * Records an exception, the full details of which will be logged, and the * message of which will be presented to the user at a later * time. If your Module calls something that you worry may fail, you should * catch the exception and pass it into this. */ void addError(Throwable t); /** * Records an error message to be presented to the user at a later time. */ void addError(Message message); /** * Returns the provider used to obtain instances for the given injection key. * The returned provider will not be valid until the {@link Injector} has been * created. The provider will throw an {@code IllegalStateException} if you * try to use it beforehand. * */ Provider getProvider(Key key); /** * Returns the provider used to obtain instances for the given injection key. * The returned provider will be attached to the injection point and will * follow the nullability specified in the dependency. * Additionally, the returned provider will not be valid until the {@link Injector} * has been created. The provider will throw an {@code IllegalStateException} if you * try to use it beforehand. */ Provider getProvider(Dependency dependency); /** * Returns the provider used to obtain instances for the given injection type. * The returned provider will not be valid until the {@link Injector} has been * created. The provider will throw an {@code IllegalStateException} if you * try to use it beforehand. */ Provider getProvider(Class type); /** * Returns the members injector used to inject dependencies into methods and fields on instances * of the given type {@code T}. The returned members injector will not be valid until the main * {@link Injector} has been created. The members injector will throw an {@code * IllegalStateException} if you try to use it beforehand. * * @param typeLiteral type to get members injector for */ MembersInjector getMembersInjector(TypeLiteral typeLiteral); /** * Returns the members injector used to inject dependencies into methods and fields on instances * of the given type {@code T}. The returned members injector will not be valid until the main * {@link Injector} has been created. The members injector will throw an {@code * IllegalStateException} if you try to use it beforehand. * * @param type type to get members injector for */ MembersInjector getMembersInjector(Class type); /** * Binds a type converter. The injector will use the given converter to * convert string constants to matching types as needed. * * @param typeMatcher matches types the converter can handle * @param converter converts values */ void convertToTypes(Matcher> typeMatcher, TypeConverter converter); /** * Registers a listener for injectable types. Guice will notify the listener when it encounters * injectable types matched by the given type matcher. * * @param typeMatcher that matches injectable types the listener should be notified of * @param listener for injectable types matched by typeMatcher */ void bindListener(Matcher> typeMatcher, TypeListener listener); /** * Registers listeners for provisioned objects. Guice will notify the * listeners just before and after the object is provisioned. Provisioned * objects that are also injectable (everything except objects provided * through Providers) can also be notified through TypeListeners registered in * {@link #bindListener}. * * @param bindingMatcher that matches bindings of provisioned objects the listener * should be notified of * @param listeners for provisioned objects matched by bindingMatcher */ void bindListener(Matcher> bindingMatcher, ProvisionListener... listeners); /** * Returns a binder that uses {@code source} as the reference location for * configuration errors. This is typically a {@link StackTraceElement} * for {@code .java} source but it could any binding source, such as the * path to a {@code .properties} file. * * @param source any object representing the source location and has a * concise {@link Object#toString() toString()} value * @return a binder that shares its configuration with this binder */ Binder withSource(Object source); /** * Returns a binder that skips {@code classesToSkip} when identify the * calling code. The caller's {@link StackTraceElement} is used to locate * the source of configuration errors. * * @param classesToSkip library classes that create bindings on behalf of * their clients. * @return a binder that shares its configuration with this binder. */ Binder skipSources(Class... classesToSkip); /** * Creates a new private child environment for bindings and other configuration. The returned * binder can be used to add and configuration information in this environment. See {@link * PrivateModule} for details. * * @return a binder that inherits configuration from this binder. Only exposed configuration on * the returned binder will be visible to this binder. */ PrivateBinder newPrivateBinder(); /** * Instructs the Injector that bindings must be listed in a Module in order to * be injected. Classes that are not explicitly bound in a module cannot be * injected. Bindings created through a linked binding * (bind(Foo.class).to(FooImpl.class)) are allowed, but the * implicit binding (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. *

* In the absence of an explicit binding for the target, linked bindings in * child injectors create a binding for the target in the parent. Since this * behavior can be surprising, it causes an error instead if explicit bindings * are required. To avoid this error, add an explicit binding for the target, * either in the child or the parent. */ void requireExplicitBindings(); /** * Prevents Guice from constructing a {@link Proxy} when a circular dependency * is found. By default, circular proxies are not disabled. *

* If a parent injector disables circular proxies, then all child injectors * (and private modules within that injector) also disable circular proxies. * If a parent does not disable circular proxies, a child injector or private * module may optionally declare itself as disabling circular proxies. If it * does, the behavior is limited only to that child or any grandchildren. No * siblings of the child will disable circular proxies. */ void disableCircularProxies(); /** * Requires that a {@literal @}{@link Inject} annotation exists on a constructor in order for * Guice to consider it an eligible injectable class. By default, Guice will inject classes that * have a no-args constructor if no {@literal @}{@link Inject} annotation exists on any * constructor. *

* If the class is bound using {@link LinkedBindingBuilder#toConstructor}, Guice will still inject * that constructor regardless of annotations. */ void requireAtInjectOnConstructors(); /** * Requires that Guice finds an exactly matching binding annotation. This disables the * error-prone feature in Guice where it can substitute a binding for * {@literal @}Named Foo when attempting to inject * {@literal @}Named("foo") Foo. */ void requireExactBindingAnnotations(); /** * Adds a scanner that will look in all installed modules for annotations the scanner can parse, * and binds them like {@literal @}Provides methods. Scanners apply to all modules installed in * the injector. Scanners installed in child injectors or private modules do not impact modules in * siblings or parents, however scanners installed in parents do apply to all child injectors and * private modules. */ void scanModulesForAnnotatedMethods(ModuleAnnotatedMethodScanner scanner); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy