上篇讲了dagger2的使用,这篇将对具体怎么注入做一个分析。
dagger2采用的是APT技术,在编译期间生成java代码,对于注解而言,有效的避免了运行时注解通过反射解析注解信息而影响效率问题。
下面是apt在编译期间自动生成的文件。
文件名生成的具体规则是:
Component: "Dagger" + 类名
工厂类:类名 + “_” + 方法名 + “Factory”
注入器:类名+"_MembersInjector"
下面做具体的源码分析:
DaggerUserComponet.builder()
.httpComponet(App.getHttpComponet())
.userModule(new UserModule(this))
.build()
.inject(this);//这一步是做真正的注入
首先在activity进行初始化,DaggerUserComponent需要两个参数,一个是UserModule,另外一个是HttpComponet,这里采用的是Builder的设计模式。
public static Builder builder() {
return new Builder();
}
public static final class Builder {
private UserModule userModule;
private HttpComponet httpComponet;
private Builder() {}
public Builder userModule(UserModule userModule) {
this.userModule = Preconditions.checkNotNull(userModule);
return this;
}
public Builder httpComponet(HttpComponet httpComponet) {
this.httpComponet = Preconditions.checkNotNull(httpComponet);
return this;
}
public UserComponet build() {
Preconditions.checkBuilderRequirement(userModule, UserModule.class);
Preconditions.checkBuilderRequirement(httpComponet, HttpComponet.class);
return new DaggerUserComponet(userModule, httpComponet);
}
}
最后调用build(),在build()先做判空处理,然后返回一个UserComponent对象。
下面我们来看怎么得到HttpComponent实例。
.httpComponet(App.getHttpComponet())
httpComponet = DaggerHttpComponet
.builder()
.httpModule(new HttpModule())
.build();
跟上面生成UserComponent对象是一个流程。
//DaggerHttpComponet
private DaggerHttpComponet(HttpModule httpModuleParam) {
initialize(httpModuleParam);
}
private void initialize(final HttpModule httpModuleParam) {
this.getOkHttpClientProvider =
DoubleCheck.provider(HttpModule_GetOkHttpClientFactory.create(httpModuleParam));
}
//HttpModule_GetOkHttpClientFactory
public static HttpModule_GetOkHttpClientFactory create(HttpModule module) {
return new HttpModule_GetOkHttpClientFactory(module);
}
在DaggerHttpComponet的构造方法中先调用initialize(),initialize()主要是创建一个Provider对象。
重点看
DoubleCheck.provider()
DoubleCheck是用来保证单例的类,因为在HttpComponent类中用@Singleton修饰。
@Singleton
@Component(modules = {HttpModule.class})
public interface HttpComponet {
OkHttpClient getOkHttpClient();
}
public static , T> Provider provider(P delegate) {
checkNotNull(delegate);
if (delegate instanceof DoubleCheck) {
/* This should be a rare case, but if we have a scoped @Binds that delegates to a scoped
* binding, we shouldn't cache the value again. */
return delegate;
}
return new DoubleCheck(delegate);
}
@Override
public T get() {
Object result = instance;
if (result == UNINITIALIZED) {
synchronized (this) {
result = instance;
if (result == UNINITIALIZED) {
result = provider.get();
instance = reentrantCheck(instance, result);
/* Null out the reference to the provider. We are never going to need it again, so we
* can make it eligible for GC. */
provider = null;
}
}
}
return (T) result;
}
在provider()中,如果传入的对象属于DoubleCheck,则直接返回,如果不是,则new DoubleCheck(delegate)。
DoubleCheck实现Provider接口,重写get()方法。在get()中就是类似双检测模式的单例方法。
最后调用build()创建一个实例。
在activity中最后调用inject()进行真正的注入。
@Override
public void inject(MainActivity mainActivity) {
injectMainActivity(mainActivity);
}
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectApiService_dev(
instance, UserModule_GetHttpServiceFactory.getHttpService(userModule));
MainActivity_MembersInjector.injectApiService_release(
instance, UserModule_GetHttpServiceFactory.getHttpService(userModule));
MainActivity_MembersInjector.injectUserManager(instance, getUserManager());
return instance;
}
public static void injectUserManager(MainActivity instance, UserManager userManager) {
instance.userManager = userManager;
}
private UserManager getUserManager() {
return UserModule_GetUserManagerFactory.getUserManager(
userModule, getApiService(), UserModule_GetUserStoreFactory.getUserStore(userModule));
}
public static UserManager getUserManager(
UserModule instance, ApiService apiService, UserStore userStore) {
return Preconditions.checkNotNull(
instance.getUserManager(apiService, userStore),
"Cannot return null from a non-@Nullable @Provides method");
}
@Provides
public UserManager getUserManager(ApiService apiService,UserStore userStore){
return new UserManager(apiService,userStore);
}
inject()调用的是injectMainActivity(mainActivity),在injectMainActivity中调用的工厂获取对应的得实例,并且赋值。最后返回activity.这样就把所需要的对象创建出来,并进行初始化,我们就可以在对应的类中进行使用。
dagger的使用:juejin.cn/post/688271…