Dagger2 使用方法

Dagger 2

依赖注入框架

资料

Github

官网

API

文档翻译

导入

  • 配置模组的 build.gradle
dependencies {
  dependencies {
    compile 'com.google.dagger:dagger:2.7'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.7'
  }
}

基本用法

构造

@Inject

  • 可以注入成员变量、构造方法、成员方法
// 在 Bean 的构造方法上添加注解 @Inject,只能注解一个构造方法,编译后生成 Xxx_Factory
@Inject
public Dog() {}

// 创建接口 @Component,作为注入器,可以是接口或者抽象类,编译时产生类 DaggerXxxComponent
@Component
public interface DogComponent {
    // 注入方法,方法名任意,不能使用子类,编译后生成 Xxx_MembersInjector
    void inject(MainActivity activity);
}

// 在需要注入的成员变量上添加注解 @Inject,不能私有
@Inject
Dog dog;

// 在编译生成代码后,注入
DaggerDogComponent.create().inject(this);

模组

@Module@Provides

  • @Inject@Provides组成对象表,需注入对象时在表中查询
  • @Module的优先级高于@Inject,优先通过@Module生成实例
// 在 Module 类上添加注解 @Module,编译后生成 XxxModule_ProvideXxxFactory
@Module
public class CatModule {

    @Provides  // 在生成方法上添加注解 @Provides
    Cat provideCat(String name) {
        return new Cat(name);
    }

    @Provides
    String provideString() {
        return "cat";
    }
}

// 在 Component 接口上添加注解 @Component,参数(modules)指向Module
@Component(modules = CatModule.class)
public interface CatComponent {
    void inject(MainActivity activity);
}

@Inject
Cat cat;

DaggerCatComponent.create().inject(this);

注入器

@Component

  • 如果你的@Component不是顶层的类型,那生成的component的名字将会包含它的封闭类型的名字,通过下划线连接。
@Module
public class SheepModule {
    @Provides
    Sheep provideSheep(String name) {
        return new Sheep(name);
    }
}

@Module
public class NameModule {
    private String name;

    public NameModule(String name) {  // 参数可以通过 Module 的构造方法传入
        this.name = name;
    }

    @Provides
    String provideString() {
        return name;
    }
}

// 在 Component 接口上添加注解 @Component,参数(modules)指向多个 Module
@Component(modules = {SheepModule.class, NameModule.class})
public interface SheepComponent {
    void inject(MainActivity activity);

    // 公开可见的对象图表,编译后会生成对应的方法
    Sheep newSheep();
}

@Inject
Sheep sheep;

// 在生成代码后,构建注入器添加 Module 和参数
SheepComponent component = DaggerSheepComponent.builder().nameModule(new NameModule("sheep")).build();
component.inject(this); // 注入,注入标注 @Inject 的对象
Sheep sheep = component.newSheep(); // 调用方法,获取对象

作用域

@Scope@Singleton@Reusable(测试)

  • @Scope 作用域,在作用域内保持单例,单例对象保存于Component中
  • @Singleton 单例,为@Scope的实现注解
  • @Reusable 重用,首次使用缓存起来重复使用
  • 可添加在@Provides标注的方法上或实例类上
  • Components可以有多种域注解,表明这些注解是同一个域的别名
// 自定义注解@DefaultScope
@Scope
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface DefaultScope {
}

@Module
public class HorseModule {
  @Provides @DefaultScope  // 添加注解 @DefaultScope
  Horse provideHorse() {
      return new Horse();
  }
}

@DefaultScope  // 添加注解 @DefaultScope
@Component(modules = HorseModule.class)
public interface HorseComponent {
    void inject(MainActivity activity);

    Horse newHorse();
}

@Inject
Horse horse;

// 注入的对象和获取的对象为同一对象,单例
HorseComponent component = DaggerHorseComponent.builder().build();
component.inject(this);
Horse horse = component.newHorse();

限定符

@Qualifier@Named

  • @Qualifier 限定符
  • @Named 命名,为@Qualifier的实现注解
// 自定义限定符 @RedPig 和 @BlackPig
@Qualifier
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface RedPig {
}

@Qualifier
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface BlackPig {
}

@Module
public class PigModule {
    @RedPig  // 添加限定符
    @Provides
    Pig provideRedPig() {
        return new Pig("Red Pig");
    }

    @BlackPig  // 添加限定符
    @Provides
    Pig provideBlackPig() {
        return new Pig("Black Pig");
    }
}

@Component(modules = PigModule.class)
public interface PigComponent {
    void inject(MainActivity activity);

    @RedPig  // 公开的对象表,添加限定符
    Pig newRedPig();

    @BlackPig  // 公开的对象表,添加限定符
    Pig newBlackPig();
}

@RedPig  // 添加限定符
@Inject
Pig redPig;

@BlackPig  // 添加限定符
@Inject
Pig blackPig;

DaggerPigComponent.create().inject(this);

加载

LazyProvider

  • Lazy 延迟加载,首次使用才注入
  • Provider 重新加载,每次重新注入
  • Lazy不等于单例
@Inject
Lazy duckLazy;

@Inject
Provider duckProvider;
T get()  // 获取对象

进阶用法

依赖

@Component(dependencies)

  • 相互独立的 Component,被依赖的 Component 公开对象表
@DefaultScope
@Component(modules = HorseModule.class)
public interface HorseComponent {
    void inject(ADActivity activity);
    // 依赖必须有公开的对象表
    Horse newHorse();
}

@MareScope // 作用域,和 HorseComponent 的不同
@Component(modules = MareModule.class, dependencies = HorseComponent.class)
public interface MareComponent {
    Mare newMare(); // MareModule 提供的对象表

    Horse newHorse(); // HorseComponent 提供的对象表
}

MareComponent component = DaggerMareComponent.builder().horseComponent(DaggerHorseComponent.create()).build();
Mare mare = component.newMare();
Horse horse = component.newHorse();

继承

@Subcomponent@Subcomponent.Builder

  • Component 结成一个整体,父 Component 不须公开对象列表,子 Component 自动获取所有的对象表
  • 子 Component 具备了父 Component 拥有的 Scope,也具备了自己的 Scope。不同作用域的对象存在各自的 Component 中
// 父 Component,无须公开对象表,子自动获取
@Singleton
@Component(modules = DonkeyModule.class)
public interface DonkeyComponent {
    // 声明子 Component 的获取方法,返回类型是 Subcomponent 类,方法名随意,参数是这个 Subcomponent 需要的 Modules,如 Modules 不用传参,可省略
    MuleComponent muleComponent(MuleModule module);
}

@MuleScope  // 子 Component 的 Scope 范围小于父 Component
@Subcomponent(modules = MuleModule.class)
public interface MuleComponent {
    // 父 Component 不能注入容器,子 Component 一起注入
    void inject(AHActivity activity);
}

@Inject
Donkey donkey;

@Inject
Mule mule;

DonkeyComponent donkeyComponent = DaggerDonkeyComponent.create();
MuleComponent muleComponent = donkeyComponent.muleComponent(new MuleModule()); // 通过父获取子
muleComponent.inject(this); // 子完成所有注入

多重绑定

@IntoSet@ElementsIntoSet@IntoMap(测试)

@Module
public class OneModule {
    @IntoSet  // 向 Set 返回一个元素
    @Provides
    static Pig provideOne(@RedPig Pig pig) {
        return pig;
    }
}

@Module
public class TwoModule {
    @ElementsIntoSet  // 向 Set 返回多个元素
    @Provides
    static Set provideTwo(@BlackPig Pig pig1, @BlackPig Pig pig2) {
        return new HashSet(Arrays.asList(pig1, pig2));
    }

    @ElementsIntoSet
    @Provides
    static Set primeEmpty() {
        return Collections.emptySet();  // 向 Set 返回空元素
    }
}

@Component(modules = {PigModule.class, OneModule.class, TwoModule.class})
public interface SetComponent {
    Set get(); // 显露的对象表
}

Set pigs = DaggerSetComponent.create().get(); //获取到一个 Set

你可能感兴趣的:(Dagger2 使用方法)