TreeviewCopyright © qgao 2021-* all right reserved, powered by aleen42

Binding Annotations

1 含义

说人话就是,有时候可能想要给一个接口注入一个实现类,但是这个接口有两个实现类,但这两个实现类都被放进了容器里,此时就不知道该这个接口注入哪一个实现类了。

Guice 框架模型(mental modal)中也提到过这个问题,只需要配合@Qualifer或者@BindingAnnotation(java元注解)使用即可,并且应该用在Guice map中的key为Key的对象里。

如下所示例子:

package example.pizza;

import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import javax.inject.Qualifier;

@Qualifier
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface PayPal {}

// Older code may still use Guice `BindingAnnotation` in place of the standard
// `@Qualifier` annotation. New code should use `@Qualifier` instead.
@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface GoogleCheckout {}

这些代码可以像Guice 快速上手写在单独一个java文件里,也可以直接写在使用这个注解的类里。

两种方式创建bindingsbind@Provide

final class CreditCardProcessorModule extends AbstractModule {
  @Override
  protected void configure() {
    // This uses the optional `annotatedWith` clause in the `bind()` statement
    bind(CreditCardProcessor.class)
        .annotatedWith(PayPal.class)
        .to(PayPalCreditCardProcessor.class);
  }

  // This uses binding annotation with a @Provides method
  @Provides
  @GoogleCheckout
  CreditCardProcessor provideCheckoutProcessor(
      CheckoutCreditCardProcessor processor) {
    return processor;
  }
}

然后像这样使用:

@Inject
public RealBillingService(@PayPal CreditCardProcessor processor,TransactionLog transactionLog) {
    ...
}
//或者
@Inject
public RealBillingService(@GoogleCheckout CreditCardProcessor processor,TransactionLog transactionLog) {
    ...
}

2 @Named

除了上面的方式,还可以使用@Named,它有一个String参数,通过指定具体的String,可以唯一标明一个实例:

final class CreditCardProcessorModule extends AbstractModule {
  @Override
  protected void configure() {
    bind(CreditCardProcessor.class)
      .annotatedWith(Names.named("Checkout"))   //只要在依赖时,有注解@Named("Checkout")
      .to(CheckoutCreditCardProcessor.class);   //就给注入CheckoutCreditCardProcessor
  }
}

依赖注入时:

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

但是不推荐这种@Named方式(sparingly保守使用),因为编译器无法check string,最好还是像第1小节一样自定义自己的注解来实现唯一标识。

Copyright © qgao 2021-* all right reserved,powered by Gitbook该文件修订时间: 2022-05-29 22:34:58

results matching ""

    No results matching ""