@Module
和 @Provides
对于所需依赖都可操控的情况下,使用 @Inject
和 @Component
组合已经可以达到依赖注入的目的,具体可参考这里。但是当所依赖对象是 Framework
层类型或一些第三方 jar
文件类型,我们无法在其构造器上添加 @Inject
注解,就无法使用 @Inject
和 @Component
来完成依赖注入。而 @Module
和 @Provides
就是用来解决这个问题的。
@Module
使用在类上,是专门用来提供依赖的。但是真正的依赖是通过其标注有 @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
进行实例化,这样的话,就可以通过其对象来调用方法,得到对应的依赖。例如:本例中将 BicycleModules
进行了实例化,而 BicycleModules
中有提供 Bicycle
实例的方法,需要该实例时,直接调用 bicycleModules.getBicycle()
即可。这也正是可以通过使用@Module
和 @Provides
组合来获取依赖的原因,因为依赖其实就是我们直接 new
出来的,只不过提供了获取的方法,生成类中直接调用该方法即可获取到依赖实例。
在 MainActivity
中进行调用时,可以这样写:
DaggerMobai.builder()
.bicycleModules(new BicycleModules()) // 注意这一行
.build()
.inject(this);
在上面的代码中可知,其实 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()
方法可知,正如我们上面所说,依赖的获取其实就是通过 @Module
实例直接调用对应方法获取。然后通过 @Component
的 injectXxx()
对依赖进行注入。
注:对于 @Module
而言,有几个呗 @Provider
标注的方法,就会生成几个对应的 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