标签:
这些绑定方式统称为内置绑定,相相应的还有种及时绑定。假设在解析一个依赖时假设在内置绑定中无法找到。那么Guice将会创建一个及时绑定。
一、链接绑定(LinkdedBindings)
链接绑定即映射一类型到它的实现类,比如映射TransactionLog接口到实现类DatabaseTransactionLog:
public class BillingModule extends AbstractModule { @Override protected void configure() { bind(TransactionLog.class).to(DatabaseTransactionLog.class); } }
public class BillingModule extends AbstractModule { @Override protected void configure() { bind(TransactionLog.class).to(DatabaseTransactionLog.class); bind(DatabaseTransactionLog.class).to(MySqlDatabaseTransactionLog.class); } }
二、绑定注解
某些情况下你可能想为同一种类型设置多种绑定。这就能够通过绑定注解来实现,该注解与绑定的类型用于唯一结识一个绑定,
合在一起称为Key。演示样例:
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 {}
然后在Module的configure方法中使用annotatedWith语句,例如以下:
bind(CreditCardProcessor.class).annotatedWith(PayPal.class).to(PayPalCreditCardProcessor.class);
这样就把CreditCardProcessor映射到了PayPalCreditCardProcessor。
使用方法:
public class RealBillingService implements BillingService { @Inject public RealBillingService(@PayPal CreditCardProcessor processor, TransactionLog transactionLog) { ... } }
public class RealBillingService implements BillingService { @Inject public RealBillingService(@Named("Checkout") CreditCardProcessor processor, TransactionLog transactionLog) { ... } }
bind(CreditCardProcessor.class) .annotatedWith(Names.named("Checkout")) .to(CheckoutCreditCardProcessor.class);
bind(String.class) .annotatedWith(Names.named("JDBC URL")) .toInstance("jdbc:mysql://localhost/pizza"); bind(Integer.class) .annotatedWith(Names.named("login timeout seconds")) .toInstance(10);
使用方式:
@Inject @Named("JDBC URL") private String urlGuice建议我们避免使用.toInstance来创建复杂的对象。由于这会延迟应用启动。类似地,能够使用@Provides方法实现。
当注入器须要该类型的实例时,它就会来调用该方法。
public class BillingModule extends AbstractModule { @Override protected void configure() { ... } @Provides TransactionLog provideTransactionLog() { DatabaseTransactionLog transactionLog = new DatabaseTransactionLog(); transactionLog.setJdbcUrl("jdbc:mysql://localhost/pizza"); transactionLog.setThreadPoolSize(30); return transactionLog; } }
@Provides @PayPal CreditCardProcessor providePayPalCreditCardProcessor(@Named("PayPal API key") String apiKey) { PayPalCreditCardProcessor processor = new PayPalCreditCardProcessor(); processor.setApiKey(apiKey); return processor; }
假设有异常抛出。那么异常将会被包装在ProvisionException对象中。
五、提供者绑定(Provider Bindings)
假设@Provides方法越来越复杂。我们可能会想把它们移到一个单独的类中。一个提供者类实现了Provider接口。它是一个
用于提供值的简单通用接口。
public interface Provider<T> { T get(); }
public class DatabaseTransactionLogProvider implements Provider<TransactionLog> { private final Connection connection; @Inject public DatabaseTransactionLogProvider(Connection connection) { this.connection = connection; } public TransactionLog get() { DatabaseTransactionLog transactionLog = new DatabaseTransactionLog(); transactionLog.setConnection(connection); return transactionLog; } }
public class BillingModule extends AbstractModule { @Override protected void configure() { bind(TransactionLog.class) .toProvider(DatabaseTransactionLogProvider.class); } }
bind(MyConcreteClass.class) .annotatedWith(Names.named("foo")) .to(MyConcreteClass.class); bind(AnotherConcreteClass.class) .annotatedWith(Names.named("foo")) .to(AnotherConcreteClass.class) .in(Singleton.class);
可是使用@Provides方法在某些地方有限制,比如:手动创建对象不能在AOP中使用。
正是由于这个原因,Guice使用了toConstructor()进行绑定。这须要我们使用反射来选择构造方法与处理异常。
public class BillingModule extends AbstractModule { @Override protected void configure() { try { bind(TransactionLog.class).toConstructor( DatabaseTransactionLog.class.getConstructor(DatabaseConnection.class)); } catch (NoSuchMethodException e) { addError(e); } } }
public class PayPalCreditCardProcessor implements CreditCardProcessor { private final String apiKey; @Inject public PayPalCreditCardProcessor(@Named("PayPal API key") String apiKey) { this.apiKey = apiKey; } }
b. @ImplementedBy
@ImplementedBy注解于用告诉注入器某类型的缺省实现类型是什么,这与链接绑定非常相似。
为某一类型绑定一子类型例如以下:
@ImplementedBy(PayPalCreditCardProcessor.class) public interface CreditCardProcessor { ChargeResult charge(String amount, CreditCard creditCard) throws UnreachableException; }
bind(CreditCardProcessor.class).to(PayPalCreditCardProcessor.class);
c. @ProvidedBy
@ProvidedBy注解用于告诉注入器。Provider类的实现是什么,比如:
@ProvidedBy(DatabaseTransactionLogProvider.class) public interface TransactionLog { void logConnectException(UnreachableException e); void logChargeResult(ChargeResult result); }这等价于bind(TransactionLog.class).toProvider(DatabaseTransactionLogProvider.class);
版权声明:本文博主原创文章,博客,未经同意不得转载。
标签:
原文地址:http://www.cnblogs.com/mengfanrong/p/4829214.html