Dagger系列:
- Dagger 2从浅到深(一)
- Dagger 2从浅到深(二)
- Dagger 2从浅到深(三)
- Dagger 2从浅到深(四)
- Dagger 2从浅到深(五)
- Dagger 2从浅到深(六)
- Dagger 2从浅到深(七)
- Dagger 2应用于Android的完美扩展库-dagger.android
Demo地址:
前面在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)
@Documented
public @interface Qualifier {}
@Qualifier在Dagger中的应用
@Qualifier标识构造函数
自定义@Qualifier
@Qualifier // 限定符 @Documented @Retention(RetentionPolicy.RUNTIME) public @interface Type { String value() default ""; }
创建数据类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 + '}'; } }
修改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); } }
在目标类中,注入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()); } *** }