Dagger系列(二)常用注解的使用:

Dagger系列(二)常用注解的使用:

Dagger2起源于Dagger,是一款基于Java注解来实现的完全在编译阶段完成依赖注入的开源库,主要用于模块间解耦、提高代码的健壮性和可维护性。Dagger2在编译阶段通过apt利用Java注解自动生成Java代码,然后结合手写的代码来自动帮我们完成依赖注入的工作。

Dagger2注解 :

我们在使用dagger2 的时候经常用到一些注解:

@Inject

@Inject有两个作用,一是用来标记需要依赖的变量,以此告诉Dagger2为它提供依赖;二是用来标记构造函数,Dagger2通过@Inject注解可以在需要这个类实例的时候来找到这个构造函数并把相关实例构造出来,以此来为被@Inject标记了的变量提供依赖;

@Module

@Module用于标注提供依赖的类。你可能会有点困惑,上面不是提到用@Inject标记构造函数就可以提供依赖了么,为什么还需要@Module?很多时候我们需要提供依赖的构造函数是第三方库的,我们没法给它加上@Inject注解,又比如说提供以来的构造函数是带参数的,如果我们之所简单的使用@Inject标记它,那么他的参数又怎么来呢?@Module正是帮我们解决这些问题的。

@Provides

@Provides用于标注Module所标注的类中的方法,该方法在需要提供依赖时被调用,从而把预先提供好的对象当做依赖给标注了@Inject的变量赋值;

@Component

@Component用于标注接口,是依赖需求方和依赖提供方之间的桥梁。被Component标注的接口在编译时会生成该接口的实现类(如果@Component标注的接口为CarComponent,则编译期生成的实现类为DaggerCarComponent),我们通过调用这个实现类的方法完成注入;

@Qulifier

@Qulifier用于自定义注解,也就是说@Qulifier就如同Java提供的几种基本元注解一样用来标记注解类。我们在使用@Module来标注提供依赖的方法时,方法名我们是可以随便定义的(虽然我们定义方法名一般以provide开头,但这并不是强制的,只是为了增加可读性而已)。那么Dagger2怎么知道这个方法是为谁提供依赖呢?答案就是返回值的类型,Dagger2根据返回值的类型来决定为哪个被@Inject标记了的变量赋值。但是问题来了,一旦有多个一样的返回类型Dagger2就懵逼了。@Qulifier的存在正式为了解决这个问题,我们使用@Qulifier来定义自己的注解,然后通过自定义的注解去标注提供依赖的方法和依赖需求方(也就是被@Inject标注的变量),这样Dagger2就知道为谁提供依赖了。----一个更为精简的定义:当类型不足以鉴别一个依赖的时候,我们就可以使用这个注解标示;

@Scope

@Scope同样用于自定义注解,我能可以通过@Scope自定义的注解来限定注解作用域,实现局部的单例;

@Singleton

@Singleton其实就是一个通过@Scope定义的注解,我们一般通过它来实现全局单例。但实际上它并不能提前全局单例,是否能提供全局单例还要取决于对应的Component是否为一个全局对象。一般我们会自定义一个 注解

Dagger2 常见注解的英用:

1、@component

举例(一): 用户上班使用电脑工作:

创建 component(需求方和依赖放的桥梁 必须存在):

@Component
public interface WorkComponent {
    User inject();
}

2、 @Inject

创建User:

public class User {
    Computer computer;
    @Inject
    public User(Computer computer) {
        this.computer = computer;
    }

    public void doWork(){
        computer.doWork();
    }
}

创建computer:

public class Computer {
    @Inject
    public Computer() {
    }

    public void doWork(){
        Log.i("grage","doWork");
    }
}

这个例子很简单,编码是computer 本身具有的行为,我们只是调用者

执行程序:

User user1 = DaggerWorkComponent.builder().build().inject();
user1.doWork();
//打印
I/grage: doWork

通过Inject 标注构造方法,dagger2 给我们创建了被Inject 标注的构造函数的实例:

DaggerWorkComponent 核心方法:

  @Override
  public User inject() {
    return new User(new Computer());
  }

举例二:添加一个module (我们的工具集)去调用不同的设备(printer)

3、 @Module、@Provider

1、添加module

@Module
public class WorkTools {

    @Provides
    public Printer providerPrinter(){
        return new Printer();
    }

}

2、修改component:

  DaggerWorkComponent.builder().workTools(new WorkTools()).build().inject(this);

3、调用:

    @Inject
    Printer printer;
    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_test);
        DaggerWorkComponent.builder().workTools(newWorkTools()).build().inject(this);
        printer.work();
        
        //I/grage: print

注意:在component inject 方法必须注入参数,且和返回值只能存在一个

4、@Qualifier

举例三、假如我们有两台打印机呢,一台白色打印机,一台黑色打印机该怎么处理?

这次我们用到了@Qualifier

定义白色和黑色打印机 Qualifier

@Qualifier
public @interface BlackPrinter {
}

@Qualifier
public @interface WhitePrinter {
}

修改module:

@Module
public class WorkTools {

    @Provides
    @BlackPrinter
    public Printer providerBlackPrinter(){
        return new Printer("黑色");
    }

    @Provides
    @WhitePrinter
    public Printer providerWhitePrinter(){
        return new Printer("白色");
    }
}

修改printer

public class Printer {
    private String color;
    @Inject
    public Printer(String color) {
        this.color = color;
    }

    public void work(){
        Log.i("grage",color +" print");
    }
}

调用:

    @Inject
    @BlackPrinter
    Printer blackPrinter;


    @Inject
    @WhitePrinter
    Printer whitePrinter;



    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_test);
        DaggerWorkComponent.builder().workTools(new WorkTools()).build().inject(this);
        blackPrinter.work();
        whitePrinter.work();
        }
        //2020-06-13 13:05:35.735 15055-15055/union.com.myapplication I/grage: 黑色 print
//2020-06-13 13:05:35.735 15055-15055/union.com.myapplication I/grage: 白色 print

5、@Singleton

未添加 @singleton

修改代码:

    @Inject
    @BlackPrinter
    Printer blackPrinter1;

    @Inject
    @BlackPrinter
    Printer blackPrinter2;

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_test);
        DaggerWorkComponent.builder().workTools(new WorkTools()).build().inject(this);

        Log.i("grage","blackPrinter1="+blackPrinter1);  //blackPrinter1=union.com.myapplication.lesson1.Printer@9fc99b4
        Log.i("grage","blackPrinter2="+blackPrinter2);
       // blackPrinter2=union.com.myapplication.lesson1.Printer@c9a79dd
    }

可以看到这两个对象不是同一个:

添加 @Singleton 注解;

@Singleton
@Component(modules = {WorkTools.class, UserModule.class})
public interface WorkComponent {
    void inject(MainActivity mainActivity);
}

@Module
public class WorkTools {

    @Singleton
    @Provides
    @BlackPrinter
    public Printer providerBlackPrinter(){
        return new Printer("黑色");
    }

    @Singleton
    @Provides
    @WhitePrinter
    public Printer providerWhitePrinter(){
        return new Printer("白色");
    }
}

    @Inject
    @BlackPrinter
    Printer blackPrinter1;

    @Inject
    @BlackPrinter
    Printer blackPrinter2;

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_test);
        DaggerWorkComponent.builder().workTools(new WorkTools()).build().inject(this);

        Log.i("grage","blackPrinter1="+blackPrinter1);  //blackPrinter1=union.com.myapplication.lesson1.Printer@9fc99b4
        Log.i("grage","blackPrinter2="+blackPrinter2);
       // blackPrinter2=union.com.myapplication.lesson1.Printer@9fc99b4
    }

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值