一个Component可以通过dependencies依赖另一个Component,可以获取到另一个Component提供的依赖
具体代码如下:
public interface Person {
String saySomething();
}
public class Student implements Person {
public String name;
public Student() {
this.name = "野猿新一";
}
@Override
public String saySomething() {
return String.format("我的名字叫%s啦", name);
}
}
@Module
public class PersonModule {
@Provides
public Person providePerson() {
return new Student();
}
}
注意这里为Person单独创建了一个Component然后依赖PersonModule,而不是直接把PersonModule设置给MainActivityModule
而且里面的getPerson()方法单纯提供Person对象,不像MainActivityModule中的inject()方法用于注入
@Component(modules = PersonModule.class)
public interface PersonComponent {
Person getPerson();
}
这里有别于依赖于Module的写法@Component(modules = PersonModule.class),而是直接依赖PersonComponent
@Component(dependencies = PersonComponent.class)
public interface MainActivityComponent {
void inject(MainActivity activity);
}
这里需要注意的是personComponent()方法必须调用且传递一个PersonComponent对象进入,否则在运行时会报如下错误
Caused by: java.lang.IllegalStateException: com.him.hisapp.PersonComponent must be set
at com.him.hisapp.DaggerMainActivityComponent$Builder.build(DaggerMainActivityComponent.java:45)
at com.him.hisapp.MainActivity.onCreate(MainActivity.java:20)
at android.app.Activity.performCreate(Activity.java:6041)
public class MainActivity extends AppCompatActivity {
@Inject
Person person;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainActivityComponent.builder()
.personComponent(DaggerPersonComponent.create())
.build()
.inject(this);
TextView textView = findViewById(R.id.text);
textView.setText(person.saySomething());
}
}
我们主要看下Dagger为我们生成的DaggerMainActivityComponent的源码,里面依赖了PersonComponent
在Builder.build()方法调用是会判断personComponent是否为空,空的话会抛异常,至于为什么不在为空的时候直接new一个DaggerPersonComponent出来目前我还不知道原因,还请有知道的读者评论说明下
public final class DaggerMainActivityComponent implements MainActivityComponent {
private PersonComponent personComponent;
private DaggerMainActivityComponent(Builder builder) {
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.personComponent = builder.personComponent;
}
@Override
public void inject(MainActivity activity) {
injectMainActivity(activity);
}
@CanIgnoreReturnValue
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectPerson(
instance,
Preconditions.checkNotNull(
personComponent.getPerson(),
"Cannot return null from a non-@Nullable component method"));
return instance;
}
public static final class Builder {
private PersonComponent personComponent;
private Builder() {}
public MainActivityComponent build() {
if (personComponent == null) {
throw new IllegalStateException(PersonComponent.class.getCanonicalName() + " must be set");
}
return new DaggerMainActivityComponent(this);
}
public Builder personComponent(PersonComponent personComponent) {
this.personComponent = Preconditions.checkNotNull(personComponent);
return this;
}
}
}
我们再看下Dagger为我们生成的代码再注入的整个过程中做了哪些工作
首先从MainActivity中调用DaggerMainActivityComponent.inject()开始,记得必须调用personComponent设置依赖的Component
DaggerMainActivityComponent.builder()
.personComponent(DaggerPersonComponent.create())
.build()
.inject(this);
看下DaggerMainActivityComponent中的Builder代码,卡夏是如何设置personComponent的和在build()的时候如果personComponent为空会抛出异常
public static final class Builder {
private PersonComponent personComponent;
private Builder() {}
public MainActivityComponent build() {
if (personComponent == null) {
throw new IllegalStateException(PersonComponent.class.getCanonicalName() + " must be set");
}
return new DaggerMainActivityComponent(this);
}
public Builder personComponent(PersonComponent personComponent) {
this.personComponent = Preconditions.checkNotNull(personComponent);
return this;
}
}
DaggerMainActivityComponent的inject()方法内部调用了injectMainActivity()方法
@Override
public void inject(MainActivity activity) {
injectMainActivity(activity);
}
DaggerMainActivityComponent的injectMainActivity()方法内部调用了MainActivity_MembersInjector.injectPerson()方法来完成Person的依赖注入,传入MainActivity对象和一个Person实例,而这个Person实例就是由PersonComponent的gerPerson()方法提供的
@CanIgnoreReturnValue
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectPerson(
instance,
Preconditions.checkNotNull(
personComponent.getPerson(),
"Cannot return null from a non-@Nullable component method"));
return instance;
}
我们在看下DaggerPersonComponent的getPerson()方法,里面调用了PersonModule_ProvidePersonFactory.proxyProvidePerson()
@Override
public Person getPerson() {
return PersonModule_ProvidePersonFactory.proxyProvidePerson(personModule);
}
看下PersonModule_ProvidePersonFactory.proxyProvidePerson()方法内部就明白了Persong对象最终是由PersonModule提供的
public static Person proxyProvidePerson(PersonModule instance) {
return Preconditions.checkNotNull(
instance.providePerson(), "Cannot return null from a non-@Nullable @Provides method");
}
最终再看下MainActivity_MembersInjector.injectPerson()方法,里面把生成的person对象赋值给MainActivity的person变量,最终完成依赖的注入
public static void injectPerson(MainActivity instance, Person person) {
instance.person = person;
}
总结以上的注入流程就是
MainActivityComponent依赖PersonComponent
PersonComponent依赖PersonModule
所以最终的Person对象是由Module提供的