Dagger2 使用方法

Dagger 2

依赖注入框架

资料

Github

官网

API

文档翻译

导入

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

  provided 'org.glassfish:javax.annotation:10.0-b28'
}

基本用法

构造

@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);
private Cat mCat;

// 构造 Dog 时,自动注入参数 Cat
@Inject
Dog(Cat cat) {
    mCat = cat;
}

// 在方法上添加 @Inject,完成 Dog 对象构造后,把对象注入 this 处
@Inject
setDog(){
    mCat.setDog(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);

加载

Lazy<T>Provider<T>

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

@Inject
Provider<Duck> 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<Pig> provideTwo(@BlackPig Pig pig1, @BlackPig Pig pig2) {
        return new HashSet<Pig>(Arrays.asList(pig1, pig2));
    }

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

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

Set<Pig> pigs = DaggerSetComponent.create().get(); //获取到一个 Set<T>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值