Guice 的工作原理
github: https://github.com/google/guice/wiki/MentalModel
总的来说:
Guice
:整个框架的门面Injector
:一个依赖的管理上下文Binder
:一个接口和实现的绑定Module
:一组Binder
Provider
:bean 的提供者Key
:Binder
中对应一个Provider
Scope
:Provider
的作用域
每个绑定 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.class
的 hashcode
和注解的 hashcode
决定了 Key
的 hashcode
,getProvider
时是根据 Key
的 hashcode
来判断是否是同一个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
就分别为 -1491509781
和 349671560
。