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

Just-in-time Bindings

这个是被Guice自动进行绑定的一个操作。

  • 显式绑定:声明在Module的binding
  • 隐式绑定:或称为Just-in-time(JIT) Bindings,即没有声明在Module中的binding,当用到时,Guice将尝试创建需要用到的binding

1 @Inject Constructors

可注入的构造方法有如下两类:

  • 被@Inject显式注解过的构造方法
  • 或者虽然没有被@Inject显式注解过,但是无参构造方法,且类和构造方法必须都是public的,因为反射是有成本的。

如:

public final class Foo {
  // An @Inject annotated constructor.
  @Inject
  Foo(Bar bar) {
    ...
  }
}

public final class Bar {
  // A no-arg non private constructor.
  Bar() {}

  private static class Baz {
    // A private constructor to a private class is also usable by Guice, but
    // this is not recommended since it can be slow.
    private Baz() {}
  }
}

不能被注入的构造方法:

  • 被有被@Inject显示注解的构造方法中还有参数
  • 一个类中有多个构造方法被@Inject注解
  • 构造方法被定义在普通内部类里:内部类对其外围类有一个隐式引用,不能注入。

如:

public final class Foo {
  // Not injectable because the construct takes an argument and there is no
  // @Inject annotation.
  Foo(Bar bar) {
    ...
  }
}

public final class Bar {
  // Not injectable because the constructor is private
  private Bar() {}

  class Baz {
    // Not injectable because Baz is not a static inner class
    Baz() {}
  }
}

应用程序可以通过在Module中调用binder().requireAtInjectRequired()来强制Guice只使用@Inject注解的构造函数。当选择注入时,Guice将只考虑@Inject注解的构造函数,如果没有,则报告MISSING_CONSTRUCTOR

tip: 使用Modules.requireAtInjectOnConstructorsModule()来在构造函数需求中为@Inject选择。

2 @ImplementedBy

该注解是告诉一个类的默认实现类是啥,和Linked Bindings差不多。

@ImplementedBy(PayPalCreditCardProcessor.class)
public interface CreditCardProcessor {
  ChargeResult charge(String amount, CreditCard creditCard)
      throws UnreachableException;
}

和下面这个一样:

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

但绑定的type如果两种方法都用了,以bind()优先。

由于@ImplementedBy是编译时的依赖,因此会被运行时的bind()给覆盖。

3 @ProvidedBy

@ProvidedBy告诉Injector可以创建实例的Provider

@ProvidedBy(DatabaseTransactionLogProvider.class)
public interface TransactionLog {
  void logConnectException(UnreachableException e);
  void logChargeResult(ChargeResult result);
}

等价于:

bind(TransactionLog.class).toProvider(DatabaseTransactionLogProvider.class);

@ImplementedBy一样,上面两种情况如果都用了,以bind()为准。

4 Enforce Explicit Bindings

为了禁止隐式绑定,可以使用requireExplicitBindings

final class ExplicitBindingModule extends AbstractModule {
  @Override
  protected void configure() {
    binder().requireExplicitBindings();
  }
}

使用了之后,就必须得将所有需要注入的binding写在Module里。

Copyright © qgao 2021-* all right reserved,powered by Gitbook该文件修订时间: 2022-05-31 10:42:31

results matching ""

    No results matching ""