是一个中间人,里面存着依赖提供者和依赖需求者。在这里
@Component(modules = CarModule.class)
表示的是需要在CarModule类中去寻找依赖,void inject(Car car);这个方法是抽象的,表示需要将这些依赖应用到Car类。说白了就是Car类需要CarModule来提供依赖。
那么我们来看看@Component的官方文档。
* Annotates an interface or abstract class for which a fully-formed, dependency-injected
* implementation is to be generated from a set of {@linkplain #modules}.
说的是这个注解只能用于接口或者抽象类。将代码改成下面,输出也是一样的。
@Component(modules = CarModule.class)
public abstract class CarComponent {
public abstract void inject(Car car);
}
在上面的步骤中,我们搞定了依赖提供者,中间人,现在我们要看看依赖需求者。在这我们的需求者是Car,也就是上面写的Car类。
我们用到了@Inject注解,
@Inject
Engine engine;
上面的代码表示engine这个属性你不用像一般情况去初始化(engine= new Engine()),它能给你自动寻找依赖。但是如果是这样肯定是不行的,还需要
DaggerCarComponent
.builder()
.carModule(new CarModule())
.build()
.inject(this);
DaggerCarComponent是apt工具帮我们生成的类,实现了CarComponent接口。
通过carModule()将我们的依赖提供者传入,通过inject()将我们的Car对象传入,这样就达到了中间人的目的。
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerCarComponent implements CarComponent {
private Provider<Engine> provideEngineProvider;
private Provider<Seat> provideSeatProvider;
private Provider<Wheel> provideWheelProvider;
private MembersInjector<Car> carMembersInjector;
private DaggerCarComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
private void initialize(final Builder builder) {
this.provideEngineProvider = CarModule_ProvideEngineFactory.create(builder.carModule);
this.provideSeatProvider = CarModule_ProvideSeatFactory.create(builder.carModule);
this.provideWheelProvider = CarModule_ProvideWheelFactory.create(builder.carModule);
this.carMembersInjector = Car_MembersInjector.create(provideEngineProvider, provideSeatProvider, provideWheelProvider);
}
public static Builder builder() {
return new Builder();
}
public static CarComponent create() {
return builder().build();
}
@Override
public void inject(Car car) {
carMembersInjector.injectMembers(car);
}
}
上面的代码是自动生成的。也就是你在CarComponent接口中加了@Component注解,然后注解处理器(dagger.internal.codegen.ComponentProcessor)就能帮你生成上面的代码,要不然程序如何知道你的注解是什么意思?
后记
如果对于注解相关知识不太了解,可以看看《Java编程思想》注解那一章。我提两点:
1 不是所有注解都用到了反射,只有@Retention(RUNTIME)才可能会用到反射。关于什么是反射,这里有涉及到类加载机制,不明白的可以翻翻我之前的blog。
2 自定义注解都需要注解处理器来处理的,不然你随便定义一个注解,谁能明白?就像上面的ComponentProcessor类一样,处理@Component注解。
这章主要是入门了Dagger2,下面我们会了解
1 为什么要使用Dagger2来替代文章一开头的写法?
2 如果@Inject注解的构造器有多个怎么办?
3 如果存在依赖链怎么办呢?
Tips
学习不要贪多,一点一点的消化,逐个击破,你会发现原来自己会的很多。比如讲Dagger的时候,我们会用到注解,那就得去了解一下注解相关知识;一提到注解很多人就会想到反射,那就要去看看反射的内容;反射里面涉及了类加载机制,又可以看看JVM相关的知识。学着学着,你会发现所有的内容都是相关的,这就是一种学习的境界了。不断的联想,不断的巩固,才能不断的提高。