Guice 的工作原理

Guice 的工作原理

github: https://github.com/google/guice/wiki/MentalModel

总的来说:

  • Guice:整个框架的门面
  • Injector:一个依赖的管理上下文
  • Binder:一个接口和实现的绑定
  • Module:一组 Binder
  • Provider:bean 的提供者
  • KeyBinder中对应一个 Provider
  • ScopeProvider的作用域

每个绑定 Binding的结构如下:

public interface Binding<T> extends Element {
    Key<T> getKey();
    Provider<T> getProvider();

同时它继承了 Element,里面包含了 Source:

public interface Element {
    Object getSource();

可以看出每个绑定 Binding,包含一个键 Key和 一个提供者 Provider

  • Key唯一地确定每一个绑定。 **键 Key包含了客户代码所依赖的类型以及一个可选的标注。**你可以使用标注来区分指向同一类型的多个绑定。
    • 例如,上述的代码中,Communicator类型的就有两个键:
    • Key[type=demo.guice.Communicator, annotation=@com.google.inject.name.Named(value=communicator)]
    • Key[type=demo.guice.Communicator, annotation=@com.google.inject.name.Named(value=anotherCommunicator)]
  • 对于每一个提供者 Provider,它提供所需类型的实例:
    • 你可以提供一个类,Guice 会帮你创建它的实例。
    • 你也可以给 Guice 一个你要绑定的类的实例。
    • 你还可以实现你自己的 Provider,Guice 可以向其中注入依赖关系。
    • 例如,上述的代码中,就有一个提供者是 class demo.guice.DefaultCommunicatorImpl
  • 每个绑定还有一个可选的作用域。**缺省情况下绑定没有作用域,Guice 为每一次注入创建一个新的对象。**一个定制的作用域可以使你控制 Guice 是否创建新对象。例如,你可以使用 为每一个 HttpSession 创建一个实例。

我们可以通过如下的方式遍历每一个绑定 Binding

Injector injector = Guice.createInjector(new BasicModule());

Map<Key<?>, Binding<?>> bindings = injector.getBindings();

for (Map.Entry<Key<?>, Binding<?>> bingingEntry : bindings.entrySet()) {
    Binding binging = bingingEntry.getValue();
    Key key =  binging.getKey();
    Provider provider = binging.getProvider();
    System.out.println("Key: " + key.toString());
    System.out.println("Provider: " + provider.get().getClass());
    System.out.println("************");
}

输出如下:

Key: Key[type=com.google.inject.Stage, annotation=[none]]
Provider: class com.google.inject.Stage
************
Key: Key[type=com.google.inject.Injector, annotation=[none]]
Provider: class com.google.inject.internal.InjectorImpl
************
Key: Key[type=java.util.logging.Logger, annotation=[none]]
Provider: class java.util.logging.Logger
************
Key: Key[type=demo.guice.Communication, annotation=[none]]
Provider: class demo.guice.Communication
***********
Key: Key[type=demo.guice.Communicator, annotation=@com.google.inject.name.Named(value=communicator)]
Provider: class demo.guice.DefaultCommunicatorImpl
************
Key: Key[type=demo.guice.Communicator, annotation=@com.google.inject.name.Named(value=anotherCommunicator)]
Provider: class demo.guice.AnotherCommunicatorImpl
************

injector.getInstance(XXX.class);的过程:
先根据指定的类来 new Key()Key包括类信息 XXX.class和注解信息,XXX.classhashcode和注解的 hashcode决定了 KeyhashcodegetProvider时是根据 Keyhashcode来判断是否是同一个Key,然后取到 Provider,由 Provider提供最终的示例。
例如上面 Key[type=demo.guice.Communicator, annotation=@com.google.inject.name.Named(value=communicator)]Key[type=demo.guice.Communicator, annotation=@com.google.inject.name.Named(value=anotherCommunicator)]hashcode就分别为 -1491509781349671560

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值