美文网首页
dagger2的学习

dagger2的学习

作者: JasonChen8888 | 来源:发表于2019-10-16 15:17 被阅读0次

    基本知识概念

    依赖关系:如果在 Class A 中,有 Class B 的实例,则称 Class A 对 Class B 有一个依赖。例如 Man 中有用到一个 Car 对象,即 Man 对 Car 有一个依赖。

    依赖注入(Dependency Injection,简称 DI):是用于实现控制反转(Inversion of Control,缩写为 IoC)最常见的方式之一,就是将对象实例传入到一个对象中去
    依赖注入是一种设计模式,降低了依赖和被依赖对象之间的耦合,方便扩展和单元测试。

    控制反转:是面向对象编程中的一种设计原则,用以降低计算机代码之间耦合度。控制反转的基本思想是:借助“第三方”实现具有依赖关系的对象之间的解耦。
    一开始是对象 A 对 对象 B 有个依赖,对象 A 主动地创建 对象 B,对象 A 有主动控制权,实现了 Ioc 后,对象 A 依赖于 Ioc 容器,对象 A 被动地接受容器提供
    的对象 B 实例,由主动变为被动,因此称为控制反转。注意,控制反转不等同于依赖注入,控制反转还有一种实现方式叫“依赖查找”

    Dagger2

    Dagger2的作用目的:提供对象实例
    1、使用@Inject标注构造函数来提供依赖的对象实例的方法
    @Inject有三种情况不能使用
    A、接口没有构造函数
    B、第三方库的类不能被标注
    C、构造函数中的参数必须配置


    dagger2.png

    2、用@Provides标注的方法来提供依赖实例,方法的返回值就是依赖的对象实例,@Provides方法必须在Module中,Module 即用@Module标注的类
    Module 是提供依赖的对象实例的另一种方式。

    3、Lazy(延迟注入) : 只有在调用 Lazy<T> 的 get() 方法时才会初始化依赖实例注入依赖

    4、Provider(多个对象的注入):有时候不仅仅是注入单个实例,我们需要多个实例,这时可以使用注入Provider<T>,每次调用它的 get() 方法都会调用到 @Inject 构造函数创建新实例或者 Module 的 provide 方法返回实例

    5、Qualifier(限定符):用于module提供多同个类的多个对象的,限定区分,即:Qualifier(限定符)的作用相当于起了个区分的别名

    6、Scope(作用域):是用来确定注入的实例的生命周期的,如果没有使用 Scope 注解,Component 每次调用 Module 中的 provide 方法或 Inject 构造函数生成的工厂时都会创建一个新的实例,而使用 Scope 后可以复用之前的依赖实例,简而言之,就是复用实例
    @Scope是元注解,是用来标注自定义注解的
    例子:
    @Documented
    @Retention(RUNTIME)
    @Scope
    public @interface MyScope {}
    关键点:
    Scope 注解只能标注目标类、@provide 方法和 Component。Scope 注解要生效的话,需要同时标注在 Component 和提供依赖实例的 Module 或目标类上。Module 中 provide 方法中的 Scope 注解必须和 与之绑定的 Component 的 Scope 注解一样,否则作用域不同会导致编译时会报错

    7、Component
    Component 管理着依赖实例,根据依赖实例之间的关系就能确定 Component 的关系
    依赖关系:
    例子:

    @ManScope
    @Component(modules = CarModule.class)
    public interface ManComponent {
        void inject(Man man);
        Car car();  //必须向外提供 car 依赖实例的接口,表明 Man 可以借 car 给别人
    }
    
    @FriendScope
    @Component(dependencies = ManComponent.class)
    public interface FriendComponent {
        void inject(Friend friend);
    }
    

    注:因为 FriendComponent 和 ManComponent 是依赖关系,如果其中一个声明了作用域的话,另外一个也必须声明,而且它们的 Scope 不能相同,ManComponent 的生命周期 >= FriendComponent 的。FriendComponent 的 Scope 不能是 @Singleton,因为 Dagger 2 中 @Singleton 的 Component 不能依赖其他的 Component。

    继承关系:
    例子:

    @ManScope
    @Component(modules = CarModule.class)
    public interface ManComponent {
        void inject(Man man);   // 继承关系中不用显式地提供暴露依赖实例的接口
    }
    
    @SonScope
    @SubComponent(modules = BikeModule.class)
    public interface SonComponent {
        void inject(Son son);
    
        @Subcomponent.Builder
        interface Builder { // SubComponent 必须显式地声明 Subcomponent.Builder,parent Component 需要用 Builder 来创建 SubComponent
            SonComponent build();
        }
    }
    

    @SubComponent的写法与@Component一样,只能标注接口或抽象类,与依赖关系一样,SubComponent 与 parent Component 的 Scope 不能相同,只是 SubComponent 表明它是继承扩展某 Component 的。怎么表明一个 SubComponent 是属于哪个 parent Component 的呢?只需要在 parent Component 依赖的 Module 中的subcomponents加上 SubComponent 的 class,然后就可以在 parent Component 中请求 SubComponent.Builder。

    8、@BindsInstance
    用于再创建Component的时候绑定依赖实例,用以注入

    总结:
    1、Dagger2 依赖注入,目的就是提供对象,在dagger2提供对象有两种方式@Inject 和 @Module
    2、每个需要依赖注入的类,都需要一个Component类
    3、Qualifier(限定符):用于module提供多同个类的多个对象的
    4、Scope的作用可以让注入的对象复用
    5、Component的两种关系:依赖和继承 (Builder和build()的使用)
    6、继承关系的实现需要:(1)在 parent Component 依赖的 Module 中的subcomponents加上 SubComponent 的 class;(2)在 parent Component 中提供返回 SubComponent.Builder 的接口用以创建 SubComponent
    7、@BindsInstance的使用 被该注解过的方法需要在buider被创建之前调用

    相关文章

      网友评论

          本文标题:dagger2的学习

          本文链接:https://www.haomeiwen.com/subject/cdcumctx.html