Dagger 2从浅到深(三)

来源:互联网 发布:syntax评分软件中文版 编辑:程序博客网 时间:2024/05/29 14:01

Dagger系列:

  1. Dagger 2从浅到深(一)
  2. Dagger 2从浅到深(二)
  3. Dagger 2从浅到深(三)
  4. Dagger 2从浅到深(四)
  5. Dagger 2从浅到深(五)
  6. Dagger 2从浅到深(六)
  7. Dagger 2从浅到深(七)
  8. Dagger 2应用于Android的完美扩展库-dagger.android

前面在Dagger 2从浅到深(二)中,提到@Provides方法返回的数据类型应该是唯一的。如果多个@Provides方法返回同一个数据类型,Dagger将不知道注入哪一个实例,从而造成了“依赖迷失”。此时,只要针对每种数据类型,写一个@Provides方法即可。可是,大家所熟悉的是,方法重载是Java的多态性的重要组成。如果对@Provides方法,重载多个,必然会造成“依赖迷失”。或者是,当一个类有多个构造被@Inject注解时,Dagger 2依然不知道使用哪个构造函数创建实例?

就像在冰箱里,有橘子、苹果、香蕉等水果,怎么才能准确的拿到我们想要的水果?我们大胆设想一下,如果对这些水果编号,重新定向水果。加入苹果的编号是2。当我们取编号2时,取到的水果就应该是苹果,而不是其他的水果。

在Dagger 2中,我们同样可以做,不管是构造函数还是@Provides方法,都进行编号处理。然后,在依据编号,调用相应的构造函数(或@Provides方法)创建实例,从而解决了“依赖迷失”问题。既然这样可以,那么久尝试这么干吧,看看结果如何!

@Qualifier

@Qualifier是javax.inject包下的注解,其是限定标识符。通过这个标识,可以对IOC容器中的实例进行编号,类似于Map中的Key。我们可以通过指定编号,从而获得我们想要的实例。

package javax.inject;@Target(ANNOTATION_TYPE)@Retention(RUNTIME)@Documentedpublic @interface Qualifier {}

@Qualifier在Dagger中的应用

@Qualifier标识构造函数

  1. 自定义@Qualifier

    @Qualifier // 限定符@Documented@Retention(RetentionPolicy.RUNTIME)public @interface Type {    String value() default "";}
  2. 创建数据类AppleBean:在创建的AppleBean类中,有三个构造函数被@Inject注解,这样必然会造成了Dagger的“依赖迷失”。

    public class AppleBean {    private String name;    private double price;    private String color;    public AppleBean() {    }    public AppleBean(String color) {        this.color = color;    }    public AppleBean(String name, double price) {        this.name = name;        this.price = price;    }    @Override    public String toString() {        return "AppleBean{" +                "name='" + name + '\'' +                ", price=" + price +                '}';    }}
  3. 修改Modle,使用限定符@Type来区分不同的构造函数new出来的对象

    @Module()public class FruitModule {    //使用限定符来区别使用哪个构造函数返回对象    @Type("color")    @Provides    public AppleBean provideColorApple() {        return new AppleBean("red");    }    @Type("name")    @Provides    public AppleBean provideNameApple() {        return new AppleBean("红富士", 6.88);    }}
  4. 在目标类中,注入AppleBean实例

    public class FruitActivity extends AppCompatActivity {    ***    // 指定数据是哪个依赖提供方提供的    @Type("color")    @Inject    AppleBean appleColorBean;    @Type("name")    @Inject    AppleBean appleNameBean;    @Override    protected void onCreate(Bundle savedInstanceState) {        FruitComponent fruitComponent = DaggerFruitComponent.builder()                                                .build();        fruitComponent.inject(this);        super.onCreate(savedInstanceState);        setContentView(getLayoutId());        ButterKnife.bind(this);        initToolBar();        //  appleColorBean:AppleBean{name='null', price=0.0, color='red'}        Log.d("test", "appleColorBean:" + appleColorBean.toString());        //  appleNameBean:AppleBean{name='红富士', price=6.88, color='null'}        Log.d("test", "appleNameBean:" + appleNameBean.toString());    }    ***}

参考文档

  1. 浅析Dagger2的使用
  2. Android:dagger2让你爱不释手-基础依赖注入框架篇
  3. Android:dagger2让你爱不释手-重点概念讲解、融合篇
  4. Android:dagger2让你爱不释手-终结篇
  5. “一盘沙拉”带你入门Dagger2(一)之HelloWorld
  6. Dagger2图文完全教
  7. 为什么网上这么多dagger2教程,我还写了这篇文章。
  8. Android常用开源工具(1)-Dagger2入门
2 0
原创粉丝点击