当我们使用 @Inject 来注解一个类(Car)的构造函数时,build 项目后,Dagger 会自动生成一个 Car_Factory 类,源码如下:
// Generated by dagger.internal.codegen.ComponentProcessor (https://google.github.io/dagger).
package com.example.demo_dagger2;
public final class Car_Factory implements Factory<Car> {
// 恶汉单例,确保线程安全
private static final Car_Factory INSTANCE = new Car_Factory();
@Override
public Car get() {
return new Car();
}
public static Factory<Car> create() {
return INSTANCE;
}
/** Proxies {@link Car#Car()}.*/
public static Car newCar() {
return new Car();
}
}
-
Car_Factory类的构造采用恶汉单例模式,即当虚拟机加载 Car_Factory 类时,就会实例化一个 Car_Factory 实例(INSTANCE)
__恶汉单例确保 INSTANCE 变量在多线程环境下状态的唯一性__。因为使用 @Inject 注解一个类的构造函数时,多个Component都可以 调用 Car_Factory 来注入依赖。即使这些 Component 处于不同线程,它们调用的都是同一个 Car_Factory 实例。
-
采用简单工厂模式,外部只需要调用Car_Factory#create() 接口,即可得到一个 Car_Factory 实例
-
获取 Car_Factory 实例后只需要调用 get 接口即可获取到一个 car 对象
当我们使用 @Module 和 @Provider 来提供依赖时,build 项目后,Dagger 会自动生成一个 FatherModule_ProvideCarFactory 类,源码如下:
public final class FatherModule_ProvideCarFactory implements Factory<Car> {
private final FatherModule module;
public FatherModule_ProvideCarFactory(FatherModule module) {
assert module != null;
this.module = module;
}
@Override
public Car get() {
return Preconditions.checkNotNull(
module.provideCar(), "Cannot return null from a non-@Nullable @Provides method");
}
public static Factory<Car> create(FatherModule module) {
return new FatherModule_ProvideCarFactory(module);
}
}
-
FatherModule_ProvideCarFactory 对象的实例化需要传入一个 module(FatherModule 对象)
-
当我们调用 FatherModule_ProvideCarFactory 对象的get方法时,其实调用的就是 module.provideCar() 方法
-
为什么 FatherModule_ProvideCarFactory 不做单例处理呢? 因为一个 module 对应一个 Component。FatherModule_ProvideCarFactory 对应的就是给 FatherComponent 来调用的。 不存在多个 Component 同时调用 FatherModule_ProvideCarFactory 的情况。
ps:
已在多个框架中看到采用 Preconditions.checkNotNull() 方法来做对象的判空处理,源码如下:
public final class Preconditions {
/**
* Ensures that an object reference passed as a parameter to the calling method is not null.
*
* @param reference an object reference
* @return the non-null reference that was validated
* @throws NullPointerException if {@code reference} is null
*/
public static <T> T checkNotNull(T reference) {
if (reference == null) {
throw new NullPointerException();
}
return reference;
}
/**
* Ensures that an object reference passed as a parameter to the calling method is not null.
*
* @param reference an object reference
* @param errorMessage the exception message to use if the check fails
* @return the non-null reference that was validated
* @throws NullPointerException if {@code reference} is null
*/
public static <T> T checkNotNull(T reference, String errorMessage) {
if (reference == null) {
throw new NullPointerException(errorMessage);
}
return reference;
}
private Preconditions() {}
}