dagger2理解分享_实现解耦

来源:互联网 发布:淘宝店铺怎样加粉丝 编辑:程序博客网 时间:2024/06/06 03:37

今天给大家分享一篇关于dagger2的文章,这个也是我前几天刚刚研究透彻的一点东西,说到dagger2,首先理解依赖注入,依赖,依赖就是类与类之间的关系,比如.A类中,有一个方法,其他的类想要用A类里面的方法,需要先得到A对象,如果没有dagger2,

1. 通过接口注入
interface ClassBInterface {
void setB(ClassB b);
}
public class ClassA implements ClassBInterface {
ClassB classB;
@override
void setB(ClassB b) {
classB = b; } }
2. 通过set方法注入
public class ClassA {
ClassB classB;
public void setClassB(ClassB b) {
classB = b; } }
3. 通过构造方法注入
public class ClassA {
ClassB classB;
public void ClassA(ClassB b) {
classB = b; }
4. 通过Java注解
public class ClassA {//此时并不会完成注入,还需要依赖注入框架的支持,
如Dagger2 @inject ClassB classB; }

第四种方法就是dagger2进行的依赖注入方式,前三种都是我们自己依赖注入的,类鱼类之间的关系依赖性非常强,如果一旦A类中有一点改动,那么其他几个类都是需要改变的,这就造成耦合性,所以我们为了解耦,就要使用dagger2

参考:
深入理解Java:注解(Annotation)自定义注解入门
Java 注解 Dependency injection
深入Java Annotation注解

Dagger2
Dagger2是Dagger1的分支,由谷歌公司接手开发,目前的版本是2.0。Dagger2是受到AutoValue项目的启发。 刚开始,Dagger2解决问题的基本思想是:利用生成和写的代码混合达到看似所有的产生和提供依赖的代码都是手写的样子。
如果我们将Dagger2和1比较,他们两个在很多方面都非常相似,但也有很重要的区别,如下:
  • 再也没有使用反射:图的验证、配置和预先设置都在编译的时候执行。
  • 容易调试和可跟踪:完全具体地调用提供和创建的堆栈
  • 更好的性能:谷歌声称他们提高了13%的处理性能
  • 代码混淆:使用派遣方法,就如同自己写的代码一样
当然所有这些很棒的特点都需要付出一个代价,那就是缺乏灵活性,例如:Dagger2没用反射所以没有动态机制。
Dagger2的配置
  • 目录添加apt支持,apt是用于自动生成代码来进行依赖注入的。
项目中的build.gradle添加:
dependencies { classpath'com.android.tools.build:gradle:2.1.0' classpath'com.neenbedankt.gradle.plugins:android-apt:1.4' // NOTE: Donot place your application dependencies here; they belong //in the individualmodule build.gradle files }

apply plugin:'com.neenbedankt.android-apt' android{... }dependencies { provided'org.glassfish:javax.annotation:10.0-b28' compile'com.google.dagger:dagger:2.5' compile'com.google.dagger:dagger-compiler:2.5'}
深入研究
想要了解Dagger2,就必须要知道依赖注入的基础和这其中的每一个概念:
  • @Inject: 通常在需要依赖的地方使用这个注解。换句话说,你用它告诉Dagger这个类或者字段需要依赖注入。这样,Dagger就会构造一个这个类的实例并满足他们的依赖。
  • @Module: Modules类里面的方法专门提供依赖,所以我们定义一个类,用@Module注解,这样Dagger在构造类的实例的时候,就知道从哪里去找到需要的 依赖。modules的一个重要特征是它们设计为分区并组合在一起(比如说,在我们的app中可以有多个组成在一起的modules)。
  • @Provide: 在modules中,我们定义的方法是用这个注解,以此来告诉Dagger我们想要构造对象并提供这些依赖。
  • @Component: Components从根本上来说就是一个注入器,也可以说是@Inject和@Module的桥梁,它的主要作用就是连接这两个部分。 Components可以提供所有定义了的类型的实例,比如:我们必须用@Component注解一个接口然后列出所有的@Modules组成该组件,如 果缺失了任何一块都会在编译的时候报错。所有的组件都可以通过它的modules知道依赖的范围。
  • @Scope: Scopes可是非常的有用,Dagger2可以通过自定义注解限定注解作用域。后面会演示一个例子,这是一个非常强大的特点,因为就如前面说的一样,没 必要让每个对象都去了解如何管理他们的实例。在scope的例子中,我们用自定义的@PerActivity注解一个类,所以这个对象存活时间就和 activity的一样。简单来说就是我们可以定义所有范围的粒度(@PerFragment, @PerUser, 等等)。
  • Qualifier: 当类的类型不足以鉴别一个依赖的时候,我们就可以使用这个注解标示。例如:在Android中,我们会需要不同类型的context,所以我们就可以定义 qualifier注解“@ForApplication”和“@ForActivity”,这样当注入一个context的时候,我们就可以告诉 Dagger我们想要哪种类型的context。
我写的一个简单的例子,帮助理解https://github.com/LemonEn/dagger2