@Module 和 @Provides
對于所需依賴都可操控的情況下,使用 @Inject 和 @Component 組合已經(jīng)可以達(dá)到依賴注入的目的,具體可參考這里。但是當(dāng)所依賴對象是 Framework 層類型或一些第三方 jar 文件類型,我們無法在其構(gòu)造器上添加 @Inject 注解,就無法使用 @Inject 和 @Component 來完成依賴注入。而 @Module 和 @Provides 就是用來解決這個問題的。
@Module 使用在類上,是專門用來提供依賴的。但是真正的依賴是通過其標(biāo)注有 @Provides 的方法來提供的
@Provides 使用在方法上,是用來提供依賴的。
@Module 和 @Provides是需要配合使用的。
@Component:
@Component(modules = {BicycleModules.class})
public interface Mobai {
void inject(MainActivity mainActivity);
}
@Module:
@Module
public class BicycleModules {
@Provides
public Bicycle getBicycle(){
return new Bicycle();
}
}
MainActivity:
public class MainActivity extends AppCompatActivity {
@Inject
Bicycle mBicycle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMobai.builder().build().inject(this);
Log.d("MainActivity", mBicycle.toString());
}
}
編譯,帶有注解 @Component 的類有生成類 DaggerMobai :
public final class DaggerMobai implements Mobai {
private BicycleModules bicycleModules;
private DaggerMobai(Builder builder) {
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static Mobai create() {
return new Builder().build();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.bicycleModules = builder.bicycleModules;
}
@Override
public void inject(MainActivity mainActivity) {
injectMainActivity(mainActivity);
}
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectMBicycle(
instance, BicycleModules_GetBicycleFactory.proxyGetBicycle(bicycleModules));
return instance;
}
public static final class Builder {
private BicycleModules bicycleModules;
private Builder() {}
public Mobai build() {
if (bicycleModules == null) {
this.bicycleModules = new BicycleModules();
}
return new DaggerMobai(this);
}
public Builder bicycleModules(BicycleModules bicycleModules) {
this.bicycleModules = Preconditions.checkNotNull(bicycleModules);
return this;
}
}
}
該類還是很容易看懂的,就是將 @Component 包含的 @Module 進(jìn)行實(shí)例化,這樣的話,就可以通過其對象來調(diào)用方法,得到對應(yīng)的依賴。例如:本例中將 BicycleModules 進(jìn)行了實(shí)例化,而 BicycleModules 中有提供 Bicycle 實(shí)例的方法,需要該實(shí)例時,直接調(diào)用 bicycleModules.getBicycle() 即可。這也正是可以通過使用@Module 和 @Provides 組合來獲取依賴的原因,因?yàn)橐蕾嚻鋵?shí)就是我們直接 new 出來的,只不過提供了獲取的方法,生成類中直接調(diào)用該方法即可獲取到依賴實(shí)例。
在 MainActivity 中進(jìn)行調(diào)用時,可以這樣寫:
DaggerMobai.builder()
.bicycleModules(new BicycleModules()) // 注意這一行
.build()
.inject(this);
在上面的代碼中可知,其實(shí) build() 方法會自動 new BicycleModules(),所以這一句加不加無所謂了。
增加了@Module 和 @Provides,在 \build\generated\source\apt\debug\com\oliver\test 多生成一個文件BicycleModules_GetBicycleFactory:
public final class BicycleModules_GetBicycleFactory implements Factory<Bicycle> {
private final BicycleModules module;
public BicycleModules_GetBicycleFactory(BicycleModules module) {
this.module = module;
}
@Override
public Bicycle get() {
return provideInstance(module);
}
public static Bicycle provideInstance(BicycleModules module) {
return proxyGetBicycle(module);
}
public static BicycleModules_GetBicycleFactory create(BicycleModules module) {
return new BicycleModules_GetBicycleFactory(module);
}
public static Bicycle proxyGetBicycle(BicycleModules instance) {
return Preconditions.checkNotNull(
instance.getBicycle(), "Cannot return null from a non-@Nullable @Provides method");
}
}
2019-03-11
通過 proxyGetBicycle() 方法可知,正如我們上面所說,依賴的獲取其實(shí)就是通過 @Module 實(shí)例直接調(diào)用對應(yīng)方法獲取。然后通過 @Component 的 injectXxx() 對依賴進(jìn)行注入。
注:對于 @Module 而言,有幾個唄 @Provider 標(biāo)注的方法,就會生成幾個對應(yīng)的 XxxModule_方法名Factory 類;例如:
@Module
public class AppModule {
@Singleton
@Provides
public Bicycle providerBicycle(){
return new Bicycle();
}
@Singleton
@Provides
public Car providerCar(){
return new Car("蘭博基尼");
}
public String haha(){
return "哈哈";
}
}
會自動生成 AppModule_ProviderBicycleFactory 和 AppModule_ProviderCarFactory 兩個類,但是不會生成 AppModule_HahaFactory