|
BindingAnnotations
Binding AnnotationsOccasionally you'll want multiple bindings for a same type. For example, you might want both a PayPal credit card processor and a Google Checkout processor. To enable this, bindings support an optional binding annotation. The annotation and type together uniquely identify a binding. This pair is called a key. Defining a binding annotation requires two lines of code plus several imports. Put this in its own .java file or inside the type that it annotates. package example.pizza;
import com.google.inject.BindingAnnotation;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
public @interface PayPal {}You don't need to understand all of these meta-annotations, but if you're curious:
To depend on the annotated binding, apply the annotation to the injected parameter: public class RealBillingService implements BillingService {
@Inject
public RealBillingService(@PayPal CreditCardProcessor processor,
TransactionLog transactionLog) {
...
}Lastly we create a binding that uses the annotation. This uses the optional annotatedWith clause in the bind() statement: bind(CreditCardProcessor.class)
.annotatedWith(PayPal.class)
.to(PayPalCreditCardProcessor.class);@NamedGuice comes with a built-in binding annotation @Named that uses a string: public class RealBillingService implements BillingService {
@Inject
public RealBillingService(@Named("Checkout") CreditCardProcessor processor,
TransactionLog transactionLog) {
...
}To bind a specific name, use Names.named() to create an instance to pass to annotatedWith: bind(CreditCardProcessor.class)
.annotatedWith(Names.named("Checkout"))
.to(CheckoutCreditCardProcessor.class);Since the compiler can't check the string, we recommend using @Named sparingly. Binding Annotations with AttributesGuice supports binding annotations that have attribute values. In the rare case that you need such an annotation:
|
Sign in to add a comment
You probably wanted:
bind(CreditCardProcessor.class) .annotatedWith(Names.named("Checkout")) .to(CheckoutCreditCardProcessor.class); ^^^^^^^^in here.
jchwastowska is right!
Is there any point in specifying a concrete type if the target instance's type is already determined using string value of @Named?
Could this be used as some sort of implicit fail-over mechanism in case there's nothing (instantiable) defined using string value of @Named?