使用绑定注释的典型示例是: -
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的价值(通过我的理解)。
答案 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 docs和JSR-330的@Qualifier annotation docs