Locked History Actions

Diff for "guice/Manual/UserGuide/Bindings/BindingAnnotations"

Differences between revisions 1 and 2
Deletions are marked like this. Additions are marked like this.
Line 46: Line 46:
@Named == @Named ==
Line 65: Line 65:
Binding Annotations with Attributes
==
Binding Annotations with Attributes ==
Line 70: Line 71:
   2. Create a class that implements the annotation interface. Follow the guidelines for equals() and hashCode() specified in the Annotation Javadoc. Pass an instance of this to the annotatedWith() binding clause.    1. Create a class that implements the annotation interface. Follow the guidelines for equals() and hashCode() specified in the Annotation Javadoc. Pass an instance of this to the annotatedWith() binding clause.

バインディングアノテーション

同じ型について、複数のバインディングを指定したいこともある。 例えば、PayPal credit card processor と Google Checkout processorを使いたいとしよう。 これができるように、バインディングはバインディングアノテーションのオプションを用意している。 アノテーションとタイプの組はバインディングを一意に識別する。 この組をキーと呼ぶ。

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:

  • @BindingAnnotation tells Guice that this is a binding annotation. Guice will produce an error if ever multiple binding annotations apply to the same member.

  • @Target({FIELD, PARAMETER, METHOD}) is a courtesy to your users. It prevents @PayPal from being accidentally being applied where it serves no purpose.

  • @Retention(RUNTIME) makes the annotation available at runtime.

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);

@Named

Guice 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 Attributes

Guice supports binding annotations that have attribute values. In the rare case that you need such an annotation:

  1. Create the annotation @interface.
  2. Create a class that implements the annotation interface. Follow the guidelines for equals() and hashCode() specified in the Annotation Javadoc. Pass an instance of this to the annotatedWith() binding clause.