绑定注释的值

时间:2016-11-08 09:14:42

标签: guice

使用绑定注释的典型示例是: -

public class RealBillingService implements BillingService {
    @Inject
    public RealBillingService(@BankABC CreditCardProcessor processor,
       TransactionLog transactionLog) {
         ...
}

我想了解注释的价值,因为我无法使用其他绑定创建另一个构造函数

public class BankBillingService implements BillingService {
    @Inject
    public BankBillingService(@Bank CreditCardProcessor processor,
       TransactionLog transactionLog) {
         ...
}

在定义示例中看起来多余,所以我必须遗漏一些东西。

我能做到

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

bind(CreditCardProcessor.class)
    .annotatedWith(Bank.class)
    .to(BankCreditCardProcessor.class);

但是我仍然必须绑定两个(或更多)类

{{1}}

如果有这样做的话,就会有一堆否定Guice的价值(通过我的理解)。

1 个答案:

答案 0 :(得分:1)

绑定注释的目标是区分同一类或类型的两个不同注入键。在你引用的例子中:

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

您可以提供替代实施:

public class StripeBillingService implements BillingService {
    @Inject
    public RealBillingService(@Stripe CreditCardProcessor processor,
       TransactionLog transactionLog) {
         ...
}

或者以更高的抽象程度运作:

public class RealBillingService implements BillingService {
    @Inject
    public RealBillingService(@International CreditCardProcessor processor,
       TransactionLog transactionLog) {
         ...
}

还可以注入类似类型的多个参数:

@Inject
public RealOrderRepository(
    @Customer DataStore customerDataStore,
    @Order DataStore orderDataStore,
    @Item DataStore itemDataStore) { /* ... */ }

作为替代方案,它会在层次结构中创建多个不必要的类型,并使创建和替换泛型实现变得更加困难或不可能:

// Ideally you should have implementations like InMemoryDataStore and AwsDataStore;
// the below would force InMemoryCustomerDataStore or LocalDbItemDataStore
// regardless of whether you need them or not.

public interface CustomerDataStore extends DataStore { /* empty */ }
public interface OrderDataStore extends DataStore { /* empty */ }
public interface ItemDataStore extends DataStore { /* empty */ }

@Inject
public RealOrderRepository(
    CustomerDataStore customerDataStore,
    OrderDataStore orderDataStore,
    ItemDataStore itemDataStore) { /* ... */ }

最终,您对绑定注释的使用应该非常罕见,只是为了区分不同的注入请求,否则它们将是相同的类型。在您的示例中,如果您在同一个应用程序中同时不需要@Bank CreditCardProcessor@PayPal CreditCardProcessor,则可以绑定CreditCardProcessor一次并完成它。但是,如果它们可能共存,那么您可以将它们绑定到同一个信用卡处理器或不同的卡处理器,或者它可能需要更改。

另请参阅:Guice's BindingAnnotations docsJSR-330@Qualifier annotation docs