Dagger:快速的依赖注入for 安卓&Java
Dagger:快速的依赖注入for 安卓&Java
2014年5月8日 星期四
15:29
官网: http://square.github.io/dagger/
GitHub: https://github.com/square/dagger
JavaDocs: http://square.github.io/dagger/javadoc/index.html
注:来自我的OneNote笔记,其实官网给的教程挺好的,最好下载GitHub上的例子来看
使用方法:
例子: coffee
example.
声明依赖性:使用javax.inject.Inject注解。
注解构造方法:
|
class Thermosiphon implements Pump { private final Heater heater; @Inject Thermosiphon(Heater this.heater = heater; } ... } |
当然,Dagger支持直接注解成员变量:
|
class CoffeeMaker { @Inject Heater heater; @Inject Pump pump; ... } |
如果你的类有通过@Inject注解的成员变量,但是没有@Inject注解的构造方法,Dagger就会使用一个无参构造方法(如果存在的话)。
Dagger不支持方法注入
满足依赖关系:
默认情况下,Dagger满足依赖关系是通过调用构造方法得到的实例,比如如果要一个CoffeeMaker对象,Dagger就会调用new CoffeeMaker(),并且设置所有可注入的成员变量。
但是,下面的情况下,@Inject是不能用的:
- 接口
- 第三方的类
- 可配置的对象必须被配置。应该值得是那些经过配置才得到实例的类
这时候,我们就可以通过@providers,去注解一个方法来满足依赖。方法的返回类型就是依赖要满足的类型。
如通过provideHeater()来得到一个Heater:
|
@Provides Heater provideHeater() { return new ElectricHeater(); } |
也有可能@Providers方法必须依赖他自己:
|
@Provides Pump providePump(Thermosiphon pump) { return pump; } |
所有的@Providers方法必须属于一个module,通过对一个类进行@Module注解来实现。
|
@Module class DripCoffeeModule { @Provides Heater provideHeater() { return new ElectricHeater(); } @Provides Pump providePump(Thermosiphon pump) { return pump; } } |
按照惯例 @Providers方法都会用provide作为前缀,@Module类都用Module作为后缀。
建立一个Graph
创建一个ObjectGraph对象的方法是调用create()并传入一个Module:
|
ObjectGraph objectGraph = |
为了使用,我们需要指定模块的注入对象类。这里我们将CoffeeApp作为开始的依赖注入类:
|
class CoffeeApp implements Runnable { @Inject CoffeeMaker coffeeMaker; @Override public void coffeeMaker.brew(); } public static void main(String[] args) { ObjectGraph CoffeeApp coffeeApp = ... } } |
然后,我们配置@Module注解来注册之。
|
@Module( injects = CoffeeApp.class ) class DripCoffeeModule { ... } |
单例:@Singleton
|
//1. 标记方法 @Provides return new ElectricHeater(); } //2. 标记类 @Singleton class CoffeeMaker { ... } |
懒注入:Lazy类
|
class GridingCoffeeMaker { @Inject Lazy<Grinder> lazyGrinder; public void brew() { while (needsGrinding()) { // lazyGrinder.get().grind(); } } } |
Provider 注入:每次调用get都得到一个新的实例
|
class BigCoffeeMaker { @Inject Provider<Filter> filterProvider; public void brew(int ... for (int p = 0; p < numberOfPots; p++) { maker.addFilter(filterProvider.get()); maker.addCoffee(...); maker.percolate(); ... } } } |
Qualifiers:限定符,通过限定符来得到不同限定符的实例
|
@Qualifier @Documented @Retention(RUNTIME) public @interface Named { String value() default ""; } |
你可以创建自定义的Qualifier或者使用Named
|
class ExpensiveCoffeeMaker { @Inject @Named("water") Heater waterHeater; @Inject @Named("hot plate") Heater hotPlateHeater; ... } |
Qualifier也支持@Providers
|
@Provides @Named("hot plate") Heater provideHotPlateHeater() { return new ElectricHeater(70); } @Provides return new ElectricHeater(93); } |
静态注入:谨慎使用,不好测试和重复使用
编译阶段的校验:
Dagger包含一个注解处理器来校验Modules和Injections,这个processor是严格的,所以如果你的dagger使用有误的话会导致编译器错误。例如下面这个问题会提示错误:
|
@Module class DripCoffeeModule { @Provides Heater provideHeater(Executor executor) return new CpuHeater(executor); } } |
编辑错误信息为:
|
[ERROR] COMPILATION ERROR : [ERROR] error: No binding for required by provideHeater(java.util.concurrent.Executor) |
解决办法是提供一个得到Executor的方法,并且用@Providers注解,或者标记该module的complete=false,意思是可以允许丢失的依赖:
|
@Module(complete = false) class DripCoffeeModule { @Provides Heater return new CpuHeater(executor); } } |
如果Module中提供了没有用到的注入也会报错,如:
|
@Module(injects = Example.class) class DripCoffeeModule { @Provides Heater return new ElectricHeater(); } @Provides Chiller return new ElectricChiller(); } } |
因为Example类只用到了Heater,javac就会报错:
|
[ERROR] COMPILATION ERROR: [ERROR]: Graph validation failed: You have these unused @Provider 1. Set |
如果你的module有可能被injects 列表以外的类使用的话,可以标注module为一个library,方法如下:
|
@Module( injects = library = true ) class DripCoffeeModule { @Provides Heater return new ElectricHeater(); } @Provides Chiller return new ElectricChiller(); } } |
我们可以创建一个模块,这个模块包含了所有其他的模块Module:
|
@Module( includes = DripCoffeeModule.class, ExecutorModule.class } ) public class CoffeeAppModule { } |
Dagger的注解处理器会在编译的时候生成类似CoffeeMaker$InjectAdapter.java或者DripCoffeeModule$ModuleAdater这样的代码文件,这些文件是Dagger的实现。你不要直接使用他们,当然,Debug的时候,就很方便了。
Dagger会报错,如果一个依赖中包含多个同样的@Providers方法。但是有时候我们也需要这样做,比如在开发或者测试的时候,可以使用overvides=true标记Module来实现这一目的。
|
public class CoffeeMakerTest { @Inject CoffeeMaker @Inject Heater heater; @Before public void ObjectGraph.create(new } @Module( includes injects overrides ) static class TestModule @Provides return Mockito.mock(Heater.class); } } @Test public void Mockito.when(heater.isHot()).thenReturn(true); coffeeMaker.brew(); Mockito.verify(heater, Mockito.verify(heater, } } |
重写在下面这样的情景很适合用:
单元测试时,用一个模拟的实现替换一个真是的实现
在开发时,用一个模拟的认证替换一个真实的认证。
集成方法:
Maven:
|
<dependency> <groupId>com.squareup.dagger</groupId> <artifactId>dagger</artifactId> <version>(insert latest version)</version> </dependency> <dependency> <groupId>com.squareup.dagger</groupId> <artifactId>dagger-compiler</artifactId> <version>(insert latest version)</version> <optional>true</optional> </dependency> |
Gradle:类似,语法是 compile "groupId:artifactId:version"
Dagger:快速的依赖注入for 安卓&Java的更多相关文章
- [Android]使用Dagger 2进行依赖注入 - Producers(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/6234811.html 使用Dagger 2进行依赖注入 - P ...
- 放弃dagger?Anrdoi依赖注入框架koin
Koin 是什么 Koin 是为 Kotlin 开发者提供的一个实用型轻量级依赖注入框架,采用纯 Kotlin 语言编写而成,仅使用功能解析,无代理.无代码生成.无反射. 官网地址 优势 依赖注入好处 ...
- 用Decorator实现依赖注入,像Java一样写后台
最近闲来无事,突发奇想,也顺便练练手,于是就萌生了,能否用typescript的decorator写一个Nodejs SpringMVC,通过依赖注入,自动实现文件加载,实例化等.然后就有了这个项目. ...
- 使用 .NETCore自带框架快速实现依赖注入
Startup 在Startup的ConfigureServices()中配置DI的接口与其实现 public void ConfigureServices(IServiceCollection se ...
- [Android]使用Dagger 2依赖注入 - DI介绍(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5092083.html 使用Dagger 2依赖注入 - DI介 ...
- [Android]使用Dagger 2依赖注入 - API(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5092525.html 使用Dagger 2依赖注入 - API ...
- [Android]使用Dagger 2依赖注入 - 自定义Scope(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5095426.html 使用Dagger 2依赖注入 - 自定义 ...
- [Android]使用Dagger 2依赖注入 - 图表创建的性能(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5098943.html 使用Dagger 2依赖注入 - 图表创 ...
- Android 和 Dagger 2 中的依赖注入
原文:Dependency Injection in Android with Dagger 2 作者:Joe Howard 译者:kmyhy 在现代开发团队中到处充斥着"你一定要用依赖注入 ...
随机推荐
- hdu4554 A Famous Game 概率期望
题面 题意:n个球,2种颜色,可能有0~n个红球,每种情况的概率相同.现在从箱子里取出了$p$个球,其中有$Q$个是红球,问现在再取一个球是红球的概率为多少? 题解:因为0 ~ n的概率相同,所以每个 ...
- python基础(4)
条件判断和循环 条件判断 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,用if语句实现: age = 20 if ag ...
- bzoj2089&2090: [Poi2010]Monotonicity
双倍经验一眼题... f[i][1/2]表示以i结尾,当前符号应该是</>的最长上升子序列, 用BIT优化转移就好 =的话就不用说了吧= = #include<iostream> ...
- YII2 model where 条件拼接
熟悉Yii2的查询条件后,用Active Record查询数据非常方便. 以下我们介绍where()方法当中,条件的拼装方式. #某个值为null,会用IS NULL来生成语句: ['type' =& ...
- 《剑指offer》— JavaScript(6)旋转数组的最小数字
旋转数组的最小数字 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2, ...
- windows使用composer.phar
把composer.phar复制到php安装目录下, 新建一个composer.bat文件,编辑 @php "%~dp0composer.phar" %* 保存,然后就可以使用co ...
- Git之安装及使用
学习使用Git来管理平时自己写的demo代码和阅读的一些源码,因为一直在windows中操作所以开始学习用Git Bash操作在github上的代码.git命令和svn命令是很相似的,我觉得没有必要把 ...
- LightOJ 1065 - Number Sequence 矩阵快速幂水题
http://www.lightoj.com/volume_showproblem.php?problem=1065 题意:给出递推式f(0) = a, f(1) = b, f(n) = f(n - ...
- 【Java-GUI】homework~QQ登录界面
话说有图有真相:(图片文件自己ps吧,动态网页未添加成功,后附html源码) Java源码: import javax.swing.*; import java.awt.*; import java. ...
- 【转】ubuntu 11.04使用apt-get安装软件时一直提示E:unable to locate package
问题: VMware虚拟机安装了ubuntu 11.04,在使用apt-get安装软件时一直提示E:Unable to locate package. 百度了原因,说是要更新源,使用命令:sudo a ...