Dagger2的使用

之前已经学习了注解和依赖注入的相关知识,现在来学习Dagger2框架
dagger2的大名我想大家都已经很熟了,它是解决Android依赖注入的一个类库(DI类库)。Dagger2没有使用反射技术,而是在变异阶段使用生成代码实现完整依赖注入的框架,而且框架生成的代码就像我们自己手写的,很容易了解其原理。

一.引入Dagger2框架

添加apt插件

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.2'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
}

添加依赖包

dependencies {
    ...
    ...
    apt 'com.google.dagger:dagger-compiler:2.0'
    compile 'com.google.dagger:dagger:2.0'
    compile 'org.glassfish:javax.annotation:10.0-b28'
}

二.对象注入

Dagger2的是怎样实现依赖注入的呢?答案是,注解。最主要的注解有三个:@Inject,@Component,@Module。

Inject是什么鬼

注解@Inject用来标注目标类中所依赖的其他类,同样用注解来标注所依赖的其他类的构造函数,这样就可以让目标类中所依赖的其他类与其他类的构造函数之间有了一种无形的联系。但如果想让Dagger2框架知道刚用哪个构造函数产生依赖对象并注入到对应的位置,则还缺少一个注入器(@Component注解的类),它就相当于一个桥梁将依赖的双方连接起来。

public class UserData {
    @Inject
    public UserData(){}//产生依赖对象的构造函数
}

public class MainActivity{
    @Inject
    public UserData userData;//需要注入对象的地方

Component是什么东西

@Component是一个注解,它所标注的类是注解类,通常这样“xxxComponent”命名,并且该类只能是接口或抽象类,在Dagger2框架生成代码时会继承该类。Component注解类在目标类中所依赖的其他类与其他类的构造函数之间可以起到一个桥梁的作用。

@Component
public interface ActivityComponent {
    void injectUserdata(MainActivity mainActivity);
}

这里写图片描述
那Component注解类是怎么工作的呢:
1)首先,你要告诉注解类,依赖所在的目标类的实例
2)Component会查找目标类中用Inject注解标注的属性
3)再目标类查找到相应的属性后,会接着查找该属性对应的用Inject标注的构造函数
4)调用构造器初始化依赖对象,注入到目标类中
因此,我们也可以给Component叫另外一个名字注入器(Injector),Component会把目标类依赖的实例注入到目标类中,来初始化目标类中的依赖。
是不是很简单,现在来总结一下Dagger2最简单的使用方法:
1)用Inject注解标注目标类中需要依赖的类属性
2)用Inject注解标注被依赖类的构造函数
3)若被依赖的类还依赖于其他的类,则重复进行上面2个步骤
4)调用Component(注入器)的injectXXX(Object)方法开始注入,Object为目标类

Module有什么用

写了那么多,好像也没有用到Module注解,没他也可以啊,关它啥事?假如,目标类所依赖的类是来自第三方的类,第三方类是不允许修改的,所以根本不可能给第三方类的构造函数加上Inject注解,这时我们的Inject就失效了。既然不能有代码自动生成依赖对象,那就我们自己来做这个工作呗!Module就是用来做这个工作的,被@Module标注的类有点类似于工厂类,它封装了第三方的类库,它里面的方法基本上用来创建实例。

@Module
public class MainModule {
    private Context mContext;
    public MainModule(Context context){
        this.mContext=context;
    }
    @Provides
    ToastUtil provideToast(){
        return new ToastUtil(mContext);
    }
}

@Module标注的类仅仅提供工厂方法,并不能提供类似于Component注入起的功能,我们怎么能让Component与Module有联系呢。简单修改Component注解类的代码:@Component(modules = MainModule.class),就能将@Module标注的类纳入到Component的管理。Component中的modules属性可以把Module加入Component,modules可以加入多个Module。

@Component(modules = MainModule.class)
public interface ActivityComponent {
    void injectUserdata(MainActivity mainActivity);
}

@Provides注解主要用于解决第三方类库依赖注入问题,Module中的创建类实例方法用Provides进行标注,Component在搜索到目标类中用Inject注解标注的属性后,Component就会去Module中去查找用Provides标注的对应的创建类实例方法,这样就可以解决第三方类库用dagger2实现依赖注入了。

使用Dagger2的最后一步

在完成以上的工作后,我们已经Make Project(command+F9)一下,Dagger2框架就能帮我们生成DaggerActivityComponent类,接着在Activity的onCreate方法中调用以下方法就能为当前的activity注入依赖。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ....
    ActivityComponent ac= DaggerActivityComponent.builder().mainModule(new MainModule(MainActivity.this)).build();
    ac.injectUserdata(MainActivity.this);
    ....
}

总结

Inject,Component,Module,Provides是dagger2中的最基础最核心的知识点:
Inject主要是用来标注目标类的依赖和依赖的构造函数
Component它是一个桥梁,一端是目标类,另一端是目标类所依赖类的实例,它也是注入器(Injector)负责把目标类所依赖类的实例注入到目标类中,同时它也管理Module。
Module和Provides是为解决第三方类库而生的,Module是一个简单工厂模式,Module可以包含创建类实例的方法,这些方法用Provides来标注

参考链接:http://www.jianshu.com/p/cd2c1c9f68d4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值