绑定注解(Binding Annotations)


Binding Annotations

在某些情况下,同一个类型可能需要多个绑定。例如,你可能同时需要PayPal credit card processor和Google Checkout processor。为了支持这种场景,Guice提供了一个可选的绑定注解。绑定注解和类型一起唯一确定一个绑定,这两者合在一起称之为一个key

定义一个绑定直接需要两行代码和一些imports,你可以将这些定义在一个.java文件中或者要注解的类中。

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 {}

通常你无需理解上面的这些元注解(meta annotation),但是如果你比较好奇,下面是一些简单的介绍:

  • @BindingAnnotation告诉Guice这是一个绑定注解。请注意,如果多个绑定注解用在同一个变量上,Guice将会报错。
  • @Target({FIELD, PARAMETER, METHOD})是对用户的一种友好的帮助,它避免用户将@PayPal注解用在它不该出现的地方。(只能用于成员变量、参数和方法上)
  • @Retention(RUNTIME)表示这是一个运行时注解。

然后,在使用绑定注解时,只需要将注解用在即将被Guice注入的参数上,例如:

public class RealBillingService implements BillingService {

  @Inject
  public RealBillingService(@PayPal CreditCardProcessor processor,
      TransactionLog transactionLog) {
    ...
  }

最后,我们需要创建一个使用注解的绑定,方法是在bind()语句中加上annotatedWith

bind(CreditCardProcessor.class)
        .annotatedWith(PayPal.class)
        .to(PayPalCreditCardProcessor.class);

(这样,只有在注解了@PayPal的参数或成员,才会被Guice注入PayPalCreditCardProcessor实例)

@Named

Guice还提供了一种内置的绑定注解@Named,它接受一个字符串作为参数:

public class RealBillingService implements BillingService {

  @Inject
  public RealBillingService(@Named("Checkout") CreditCardProcessor processor,
      TransactionLog transactionLog) {
    ...
  }

在使用时,通过Names.named()创建一个实例传递给annotatedWith()方法,就可以绑定一个具体的名字。

bind(CreditCardProcessor.class)
        .annotatedWith(Names.named("Checkout"))
        .to(CheckoutCreditCardProcessor.class);

这样,只有在注解了@Named("Checkout")的参数或成员,才会被Guice注入CheckoutCreditCardProcessor实例

但是,由于编译器无法检查@Named中的String,因此不建议过多的使用@Named注解。通过自定义的绑定注解来实现相同的功能是一种更好的选择,它可以保证类型安全。

带属性的绑定注解

Guice支持带属性值的绑定注解(例如@Named)。如果在极少见的情况下,你需要使用到这样的绑定注解(并且无法使用@Provides方法),我们建议你使用Auto/Value项目中的@AutoAnnotation,因为实现一个这样的注解是非常容易出错的。当然,如果你确定要手动创建一个自定义的实现也是可以的,必须确保根据Annotation Javadoc中的描述正确地实现了equals()方法和hashCode()方法。在这之后,将你创建的注解类的实例传入annotatedWith()方法即可。

results matching ""

    No results matching ""