Dagger - 快速依赖注入器(for android and java) (1)
引言 在程序中, 最重要的类是那些真正实现 相反, 程序中最不重要的类是辅助类(take up space without doing much at all): BarcodeDecoderFactory(条形码解析器工厂),CameraServiceLoader(相机服务加载器),和 MutableContextWrapper(易变环境变量包装器).这些辅助类就像笨拙的胶带一样,将那些重要的功能类连接起来。 Dagger 就是这些工厂类的终结者。 它帮助你专注在那些重要的功能类上。通过声明依赖关系, 指定规则, 构建整个应用程序。 Dagger 构建在标准的javax.injectannotation基础之上,每一个类都很容易测试。你也不需要为了便于将 RpcCreditCardService 替换为 FakeCreditCardService, 而构建一堆的样板(boilerplate)。 更多信息请移步watch an introductory talk by Jesse Wilson at QCon 2012.
Using Dagger接下来, 我们通过构建一个Coffer Maker 来说明 依赖注入 和 Dagger。你可以下载完整的Coffee Maker示例代码, 编译调试。 声明依赖关系 Dagger 构造应用程序的类对象,并组合其依赖关系。 Dagger使用 Dagger将使用 class Thermosiphon implements Pump { private final Heater heater; @Inject Thermosiphon() { this.heater = ; } ... } Dagger 可以直接注入成员变量。在这个例子中, 它获取Heater对象, 并注入到成员变量heater,同时获取Pump对象并注入到成员变量pump。 CoffeeMaker {
@Inject ;
Pump pump;
当类中含有@Inject注释的成员变量, 却没有@Inject注释的构造函数时, Dagger将使用类的默认构造函数。若类中缺少@Inject注释, 该类是不能由Dagger创建的。
Dagger不支持函数注入。
实现依赖关系(Satisfying Dependencies, 实在想不出合适的中文对应) 默认情况下, Dagger 通过构造相应类型的对象来实现依赖关系。当请求一个CoffeMaker对象时, Dagger将调用new CoffeeMaker()构造函数, 并赋值给@Inject标记的成员变量。 但是@Inject并不是在任何情况下都可以:
对那些使用@Inject效率极低或者awkward的情况, 可以使用@Provides注释函数来实现依赖关系。这些函数的返回类型定义其实现的依赖关系。 例如, 当需要一个Heater时, Dagger将调用provideHeater()函数获取。 @Provides provideHeater() {
return new ElectricHeater();
@Provides注释的函数也可以有他们自己的依赖关系。下面这个Provides函数依赖于一个Thermosiphon对象:
providePumpThermosiphon return ;
所有的@Provides函数必须属于一个Module。这些Module类使用@Module注释。
@Module
DripCoffeeModule ();
}
}
通常情况下, 约定@Provides函数以provide作为前缀, @Module类以Module作为后缀。
构建ObjectGraph(对象图表) @Inject 和 @Provides 注释的类构建了一个对象图表。这些对象与对象之间通过依赖关系相互关联。通过函数 ObjectGraph objectGraph ObjectGraphcreate(new DripCoffeeModule());
我们需要引导注入来使用这个对象图表。 对于命令行程序, 通常需要注入一个主程序类;对于Android程序,通常需要注入activity类。在这个coffer例子中, CoffeeApp被用于引导注入。我们请求这个对象图表构建一个CoffeeApp的对象实例: CoffeeApp Runnable CoffeeMaker coffeeMaker@Override public void run{
brew}
public static void mainString[] args());
CoffeeApp coffeeApp objectGraphgetCoffeeAppclass);
...
这里唯一缺少的是:这个对象图表并不知道CoffeeApp这个可注入类。我们需要在@Module注释中显式的声明。
@Module(
injects class
)
{
injects选项使得可以在编译的过程中检查对象图表是有有效, 从而更早的检测问题,以加快开发速度,降低重构时的风险。 现在, 对象图表已经构建好, 根对象也已被注入, 我们就可以运行这个Coffee 程序了。 $ java -cp ... coffee.CoffeeApp ~ ~ ~ heating ~ ~ ~ => => pumping => => [_]P coffee! [_]P (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |