在Guice中,注入方式有如下几种:

一、构造器注入(Constructor Injection)

使用构造器注入只要在构造方法上添加一个@Inject注解,该构造方法接收一些依赖参数,大多数的构造方法将这些参数赋值给final字段。

public class RealBillingService implements BillingService {  private final CreditCardProcessor processorProvider;  private final TransactionLog transactionLogProvider;  @Inject  public RealBillingService(CreditCardProcessor processorProvider,      TransactionLog transactionLogProvider) {    this.processorProvider = processorProvider;    this.transactionLogProvider = transactionLogProvider;  }}

如果有一个类没有添加了@Inject注解的构造方法,那么Guice使用一个public的、没有参数的构造方法,如果该构造方法存在的话。

构造器依赖易于单元测试,如果你类在一个唯一的构造方法中接收所有参数,这样你就不会忘记去设置依赖。当一个新的依赖产生了,所有的调用代码很容易修改,更正掉编译错误你就完事大吉了。

二、方法注入(Method Injection)

Guice可以通过冠以@Inject注解的访求进行注入。依赖采用参数的形式,在调用方法之前注入器会解析依赖。被注入方法可以有任意多的参数,并且方法名称不会影响注入。

public class PayPalCreditCardProcessor implements CreditCardProcessor {  private static final String DEFAULT_API_KEY = "development-use-only";  private String apiKey = DEFAULT_API_KEY;  @Inject  public void setApiKey(@Named("PayPal API key") String apiKey) {//该方法会被Guice调用并注入值    this.apiKey = apiKey;  }}

三、字段注入(Field Injection)

Guice可以通过冠以@Inject注解的字段进行注入,这是最简洁的注入方式,但是却最不利于测试。示例:

public class DatabaseTransactionLogProvider implements Provider<TransactionLog> {  @Inject Connection connection;  public TransactionLog get() {    return new DatabaseTransactionLog(connection);  }}

四、可选注入(Optional Injections)

有的时候需要一个依赖对象存在则进行注入,如果不存在则不进行注入,这样是比较方便的。方法与字段注入可以是可选的,这样当依赖对象不可用的时候Guice就会忽略这些注入。要使用可能的注入,使用@Inject(optional=true)注解。

public class PayPalCreditCardProcessor implements CreditCardProcessor {  private static final String SANDBOX_API_KEY = "development-use-only";  private String apiKey = SANDBOX_API_KEY;  @Inject(optional=true)  public void setApiKey(@Named("PayPal API key") String apiKey) {    this.apiKey = apiKey;  }}

当可选注入与及时绑定混在一起时,你可能会得到一个让你意外的结果。例如,如下字段总是会进行注入即使Date对象没有显示地进行绑定。但是Date类有一个公开的无参数构造方法,这就符合及时绑定条件。

@Inject(optional=true) Date launchDate;//launchDate依赖会进行注入

五、请求式注入(On-demand Injection)

方法与字段注入可以用于初始化实例对象,使用Injector.injectMembers

public static void main(String[] args) {    Injector injector = Guice.createInjector(...);    CreditCardProcessor creditCardProcessor = new PayPalCreditCardProcessor();//手动创建而不是从容器中获取    injector.injectMembers(creditCardProcessor);//会为creditCardProcessor中需要注入的成员进行注入}

六、静态注入

当一个应用从静态工厂迁移到Guice上来时,静态注入就是一有效手段。在Module类中使用requestStaticInjection()方法,这样就可能对类中冠以@Inject注解的静态字段进行注入。

@Override public void configure() {    requestStaticInjection(ProcessorFactory.class);    ...}class ProcessorFactory {  @Inject static Provider<Processor> processorProvider;  /**   * @deprecated prefer to inject your processor instead.   */  @Deprecated  public static Processor getInstance() {    return processorProvider.get();  }}

文档中说静态成员在使用实例注入(instance-injection)时无效,但经本人测试实例注正常,不论是静态成员还是实例成员。

但这个API已经不被建议使用,因为它存在很多静态工厂类似问题:难于测试,使依赖透明化,依赖于全局状态等。

七、自动注入(Automatic Injection)

以下情形Guice会进行自动注入:

a. 传递给toInstance()语句的实例

b. 传递toProvider()语句的Provider对象,这些对象会在注入器创建时进行注入

-------------------------------- END -------------------------------

及时获取更多精彩文章,请关注公众号《Java精讲》。

©著作权归作者所有:来自51CTO博客作者Java精讲的原创作品,如需转载,请注明出处,否则将追究法律责任

你的鼓励让我更有动力

赞赏

0人进行了赞赏支持

更多相关文章

  1. R语言包的安装
  2. 3种加强身份和访问管理的方法
  3. 基于帕金森数据集的分类方法仿真研究
  4. 【CSS入门】CCS基本语法和常用选择器的使用方法
  5. Python开发技巧:scrapy-redis爬虫如何发送POST请求
  6. Mac电脑设置语音详细度的方法
  7. scrapy-redis爬虫如何发送POST请求
  8. 新浪博客提示“系统繁忙,请稍候再试”的解决方法
  9. 压缩感知之稀疏度自适应匹配追踪(SAMP)方法

随机推荐

  1. 更改Edittext光标的颜色与粗细
  2. 安卓,如何让两个按钮相邻,宽度相同
  3. Android Terminal Emulator 在Desire上的
  4. Android Studio中AVD SDk找不到的解决办
  5. 极光推送实现精确对点推送机制
  6. Android学习笔记(三一):线程:Message和Runnab
  7. 使用RxJava和RxAndroid封装RxBus,实现Even
  8. 解决:AndroidStudio 下使用AIDL不能生成对
  9. 哪个移动系统适合程序员?
  10. [置顶] Android系统体系结构分析