在这篇文章中你会看到什么:bash
@Named
是什么@Qualifier
是什么@Named
和 @Qualifier
用了解决什么问题也许你会遇到这样的需求: 在同一个 Module 中 经过 @Provides 标记多个提供相同类的不一样实现对象,那么你在编译时能够会遇到相似的报错信息:框架
错误: xxxx.UserThird is bound multiple times: @Provides xxxUserThird xxxxx.UserThirdModule.provideUserThird() @Provides xxx.UserThird xxx.UserThirdModule.provideUserThirdWithoutParams()ide
其大体信息为 UserThird
类被绑定了屡次,并列举了绑定的信息。出错的缘由是咱们提供了返回值相同的建立类实例的方法,可是程序没有那么智能,它是没法判断出应该使用哪个方法来建立实例,因此在编译器就会抛出异常,这种现象称为 依赖注入迷失
。post
可是这样的操做在正常的业务中是在正常不过的了,是没法避免不去使用的。那么此时 @Named 和 @Qualifier 能够用来解决此类问题。ui
其具体使用方法为:this
@Named
标记 Module 中生成类实例的方法@Named
标记目标类中相应类实例两步骤是缺一不可的。咱们来看一下具体代码:spa
public class UserThird {
private String mSex = "man";
private int mCarNum = 7;
public UserThird() {
}
public UserThird(String mSex, int mCarNum) {
this.mSex = mSex;
this.mCarNum = mCarNum;
}
// 变量的setter 和 getter 方法
.....
}
复制代码
@Module
public class UserThirdModule {
@Named("a")
@Provides
UserThird provideUserThird(){
return new UserThird("男",1243);
}
@Named("b")
@Provides
UserThird provideUserThirdWithoutParams() {
return new UserThird();
}
}
复制代码
public class ThirdActivity extends AppCompatActivity {
@Named("a")
@Inject
UserThird mUserTwoC;
@Named("b")
@Inject
UserThird mUserTwoD;
private static final String TAG = "SecondActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
DaggerUserThirdComponent.builder().userThirdModule(new UserThirdModule()).build().injectToThirdActivity(this);
Log.e(TAG, "onCreate: " + "sex" + mUserTwoC.getSex() + " number:" + mUserTwoC.getCarNum());
mUserTwoC.setCarNum(46);
mUserTwoC.setSex("女");
Log.e(TAG, "onCreate: " + "sex" + mUserTwoC.getSex() + " number:" + mUserTwoC.getCarNum());
Log.e(TAG, "onCreate: " + "sex" + mUserTwoD.getSex() + " number:" + mUserTwoD.getCarNum());
}
}
复制代码
以上代码须要重点关注的是 Module 类 中使用 @Named
注解方法和在 目标类 中使用 @Named
注解标记类的实例变量,而且 Module 中的 @Named("a")
和 目标类中的 @Named("a")
是一一对应的。code
以上经过 @Named 实现的标识功能 @Qualifier 一样能够实现,可是须要咱们自定义注解来完成,具体一个使用场景以下:cdn
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface UserThirdQualifier {
String value() default "";
}
复制代码
注意,这里自定义注解须要使用 @Qualifier
进行标注。对象
@Module
public class UserThirdModule {
@UserThirdQualifier("c")
@Provides
UserThird provideUserThird(){
return new UserThird("男",1243);
}
@UserThirdQualifier("d")
@Provides
UserThird provideUserThirdWithoutParams() {
return new UserThird();
}
}
复制代码
public class ThirdActivity extends AppCompatActivity {
@UserThirdQualifier("c")
@Inject
UserThird mUserTwoC;
@UserThirdQualifier("d")
@Inject
UserThird mUserTwoD;
private static final String TAG = "SecondActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
DaggerUserThirdComponent.builder().userThirdModule(new UserThirdModule()).build().injectToThirdActivity(this);
Log.e(TAG, "onCreate: " + "sex" + mUserTwoC.getSex() + " number:" + mUserTwoC.getCarNum());
mUserTwoC.setCarNum(46);
mUserTwoC.setSex("女");
Log.e(TAG, "onCreate: " + "sex" + mUserTwoC.getSex() + " number:" + mUserTwoC.getCarNum());
Log.e(TAG, "onCreate: " + "sex" + mUserTwoD.getSex() + " number:" + mUserTwoD.getCarNum());
}
}
复制代码
一样的,以上代码须要重点关注的是 Module 类 中使用 @UserThirdQualifier
注解方法和在 目标类 中使用 @UserThirdQualifier
注解标记类的实例变量,而且 Module 中的 @UserThirdQualifier("c")
和 目标类中的 @UserThirdQualifier("c")
是一 一对应的。
经过 @Named
和 @Qualifier
两个注解就能够作到标识在同一个 Module 中提供相同类实例对象而形成的 依赖注入迷失
问题 。