这个框架它的好处是它没有采用反射技术(Spring是用反射的),而是用预编译技术,因为基于反射的DI非常地耗用资源(空间,时间)。这里记录一下上面文章的一些关键的要点
声明依赖关系
Dagger 构造应用程序的类对象,并组合其依赖关系。 Dagger使用 javax.inject.Inject
annotation 标记那些需要依赖注入的构造函数和成员变量。
Dagger将使用 @Inject 注释的构造函数
创建类对象。 当请求构建新的类对象时, Dagger 将自动获取相应的参数, 并调用构造函数。
class Thermosiphon implements Pump {
private final Heater heater;
@Inject
Thermosiphon(Heater heater) {
this.heater = heater;
}
...
}
class CoffeeMaker {
@Inject Heater heater;
@Inject Pump pump;
...
}
Dagger 可以直接注入成员变量。在这个例子中, 它获取Heater对象, 并注入到成员变量heater,
,获取Pump对象并注入到成员变量pump。
注意,当类中含有@Inject注释的成员变量, 却没有@Inject注释的构造函数时, Dagger将使用类的默认构造函数。若类中缺少@Inject注释, 该类是不能由Dagger创建的。这这个例子中,因为Thermosiphon类中有@Inject注释的构造函数,当有数要构建这个类对象的时候,就使用这个@Inject注释的构造函数来构建类的对象。
Dagger不支持函数注入。
实现依赖关系
默认情况下, Dagger 通过构造相应类型的对象来实现依赖关系。当请求一个CoffeMaker对象时, Dagger将调用new CoffeeMaker()构造函数, 并赋值给@Inject标记的成员变量。
但是@Inject并不是在任何情况下都可以:
- 接口类型不能被构造
- 第三方的类不能被注释构造。
- 可配置的对象必须被配置好
对那些使用@Inject效率极低的情况, 可以使用@Provides注释函数来实现依赖关系。这些函数的返回类型定义其实现的依赖关系。
例如, 当需要一个Heater时, Dagger将调用provideHeater()函数获取。
@Provides Heater provideHeater() {
return new ElectricHeater();
}
@Provides注释的函数也可以有他们自己的依赖关系。下面这个Provides函数依赖于一个Thermosiphon对象:
@Provides Pump providePump(Thermosiphon pump) {
return pump;
}
所有的@Provides函数必须属于一个Module。这些Module类使用@Module注释。
@Module
class DripCoffeeModule {
@Provides Heater provideHeater() {
return new ElectricHeater();
}
@Provides Pump providePump(Thermosiphon pump) {
return pump;
}
}
注意,通常情况下, 约定@Provides函数以provide作为前缀, @Module类以Module作为后缀。
构建ObjectGraph(对象图表)
@Inject 和 @Provides 注释的类构建了一个对象图表。这些对象与对象之间通过依赖关系相互关联。通过函数ObjectGraph.create()
获取这个对象图表, 这个函数可以接受一个或多个Module作为参数:
ObjectGraph objectGraph = ObjectGraph.create(new DripCoffeeModule());