在這篇文章中你會看到什麼: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 中提供相同類實例對象而形成的 依賴注入迷失
問題 。