Dagger2學習筆記1(基礎概念學習)
Dagger2學習筆記2(學習Dagger2的簡單使用)
上篇中學習了如何使用 Dagger2, 很多小伙伴可能一臉懵, 現在我們將學習 dagger2中各個注解的含義以及使用的注意事項.
Dagger2中的注解
4個基礎注解,經常使用
- @Inject
- @Module
- @Provides
- @Component
- @Named
- @Qualifier
- @Singleton
- @Scope
...
@inject
作用:
1 依賴注入類中的依賴變量聲明,讓 dagger2為其提供依賴
2 被依賴的類的構造方法上申明, 通過標記構造函數讓 Dagger2 來使用, 可以在需要這個類實例的時候來找到這個構造函數并把相關實例new出來
eg.
@Inject
BuyCarSuccessPresenterImpl mPresenter;
@Inject
public Dogs(Dog dog){
this.dog = dog;
}
@Module
作用:
1 修飾類, 與@Inject作用相同,用來提供依賴,區別在于Module為那些沒有構造方法的類如工具類等提供依賴比如,系統工具類, 第三方 Jar 包等, 能用 @Inject 提供工具類的
@Provides
作用:
用于注解被@ Module 修飾的類中的方法, 當需要該類的依賴時會去找返回值為該類的方法
@Module
public class MainModule {
@Provides
Dog provideDog(){
Dog dog = new Dog();
dog.setColor("yellow");
return dog;
}
@Component
作用:
1 注解一個接口或者抽象類,
2 為inject和module之間建立聯系,可以理解為不賺差價的中間商
eg. 在編譯時會產生對應的類的實例, 為依賴方和被依賴方提供橋梁,把相關的依賴注入到其中.
@Component(modules = MainModule.class)
public interface MainComponent{
void inject(MainActivity activity);}
抽象方法inject參數為注入的activity類, build之后會生成一個以dagger開頭mainComponent結尾的類。
public class MainActivity extends AppCompatActivity {
@Inject
Dogs dogs;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainComponent
.builder()
.mainModule(new MainModule())
.build()
.inject(this);
}
}
在activity中調用生成dagger的inject方法, 完成依賴注入
以上為四個常用的基本注解類, 除此之外還有很多非基本的注解
@Named
作用: 用于區分我們獲取依賴的方法
Dagger2尋找依賴是根據我們提供方法的返回值進行匹配的, 當我們遇到不同提供依賴的方法但是返回值類型是相同的應該怎么辦呢? Dagger2提供了 Named 注解,用于區分相同返回值類型的不同方法.
定義提供依賴的方法:
@Module
public class MainModule {
@Named("yellow")
@Provides
Dog provideYellowDog(){
Dog dog = new Dog();
dog.setColor("yellow");
return dog;
}
@Named("black")
@Provides
Dog provideBlackDog(){
Dog dog = new Dog();
dog.setColor("black");
return dog;
}
兩個提供依賴的方法返回值都是 Dog, 但是用 Named加以區分
使用:
public class SecondActivity extends BaseAcitivity {
@Inject
@Named("black")
Dog dog;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
((TextView)findViewById(R.id.tv)).setText(dog.toString());
...
}
此時拿到的對象是 BlackDog
@Qulifier
作用: 與 Named一致, Named是繼承Qulifier的, 相當于 Dagger2為我們提供的標準化的區分器, 我們也可以進行自定義:
public class MainModule {
@Provides
@YellowDog
Dog provideYellowDog(){
Dog dog = new Dog();
dog.setColor("yellow");
return dog;
}
....
}
public class MainActivity extends BaseAcitivity {
@Inject
@YellowDog
Dog dog;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
((TextView)findViewById(R.id.tv)).setText(dog.toString());
...
}
輸出結果為 YellowDog, 與 @Named("yellow")效果一致
@Singleton
作用: 聲明單例模式, Dagger2的機制是需要某個對象是回去找對應提供的實例化方法, 多次尋找就會創建多個對象, 當我們需要讓對象保持單例模式時, 要使用@Singleton修飾提供依賴的方法
使用: 修飾Module 中需要使用單例的方法上, 保證實例全局都是單例
@Module
public class MainModule {
@Singleton
@Provides
Dog provideDog(){
Dog dog = new Dog();
dog.setColor("yellow");
return dog;
}
....
}
注意: 1.module 中有方法使用Singleton修飾時, 引用 module 的 component 也要使用@Singleton修飾, 否則編譯會報錯. 2.想要使用 Singleton 保持全局單例,需要配合Component 使用@Depencies注解以及配合Applicaition 的全局單例性質才可以實現, 后文中會進行詳細介紹.
@Singleton
@Component(modules = MainModule.class)
public interface MainComponent {
}
通過構造方法提供依賴要保證單例時, 我們需要在該類的類名上使用@ Singleton 修飾, 切記不是構造方法上!
@Scope
查看源碼可以發現@Singleton是使用注解@Scope 修飾的, 而@Scope是用來聲明作用域的, Dagger2的機制:在同一作用域下,provides 提供的依賴對象會保持單例, 脫離這一作用域, 單例作用就會失效, 可以說 @Singleton 是@Scope 注解的一個標準, 我們還可以去自定義一些 Scope 注解.
@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}
Scope注解需要我們進行自定義, 自定義方法和 Singleton作用一致, 當我們使用 @Dependies 進行 Component間的依賴的時候, 如果有提供單例的依賴, 根據 dagger2的機制, 這時我們依賴的Component不能使用同一 scope 進行修飾, 否則會報錯, 所以就用到了自定義的scope, 從而區分 Component 之間的層級關系.
下一篇中我們將學習Singleton如何實現全局單例.
Dagger2學習筆記4(@Singleton 與@ Scope 實現全局單例與作用域單例)
Dagger2學習筆記5(關于Lazy,Provide的使用)
End~
特別謝明:Dagger2 入門,以初學者角度