Code example
class Tiger {
public void sleep() {
System.out.println("Tiger sleeping");
}
}
@Module
class ZooModule {
@Singleton // 注意这里
@Provides
public Tiger providerTiger() {
return new Tiger();
}
}
@Singleton // 注意这里
@Component(modules = {
ZooModule.class})
interface ZooComponent {
Zoo inject(Zoo zoo);
}
public class Zoo {
@Inject
Tiger tiger;
@Test
public void 案例八() {
DaggerZooComponent.create().inject(this);
tiger.sleep();
}
}
Dagger2 generated code reading
After the main analysis is
@Singleton
annotated, theTiger
object is a singleton object in the same syringe life cycle.
Looking at the code generated by Degger2 based on the above case, the generated code is in the build\generated\sources\annotationProcessor\..
folder.
DaggerZooComponent.create()
final class DaggerZooComponent implements ZooComponent {
private Provider<Tiger> providerTigerProvider;
private DaggerZooComponent(ZooModule zooModuleParam) {
// 该方法最终创建一个Provider对象,它持有ZooModule_ProviderTigerFactory对象.
initialize(zooModuleParam);
}
private void initialize(final ZooModule zooModuleParam) {
// ZooModule_ProviderTigerFactory.create(zooModuleParam)创建一个ZooModule_ProviderTigerFactory对象,它的父类其实是Provider.
// DoubleCheck.provider():创建DoubleCheck对象.
this.providerTigerProvider = DoubleCheck.provider(ZooModule_ProviderTigerFactory.create(zooModuleParam));
}
static final class Builder {
private ZooModule zooModule;
private Builder() {
}
public Builder zooModule(ZooModule zooModule) {
this.zooModule = Preconditions.checkNotNull(zooModule);
return this;
}
// 创建注射器对象
public static ZooComponent create() {
return new Builder().build();
}
public ZooComponent build() {
if (zooModule == null) {
// ZooModule对象在这里被创建
this.zooModule = new ZooModule();
}
// 创建注射器对象DaggerZooComponent.
return new DaggerZooComponent(zooModule);
}
}
}
- It needs to be cleaned up before injecting the object
DoubleCheck.provider()
.ZooModule_ProviderTigerFactory.create(zooModuleParam)
public final class ZooModule_ProviderTigerFactory implements Factory<Tiger> {
// 该方法主要用来创建ZooModule_ProviderTigerFactory对象,它的父类其实是Provider.
public static ZooModule_ProviderTigerFactory create(ZooModule module) {
return new ZooModule_ProviderTigerFactory(module);
}
}
Look againDoubleCheck.provider()
public final class DoubleCheck<T> implements Provider<T>, Lazy<T> {
public static <P extends Provider<T>, T> Provider<T> provider(P delegate) {
...
// delegate:是ZooModule_ProviderTigerFactory对象,他的父类是Provider.
return new DoubleCheck<T>(delegate);
}
// 它最终将ZooModule_ProviderTigerFactory对象存储起来了.
private DoubleCheck(Provider<T> provider) {
assert provider != null;
this.provider = provider;
}
}
.inject(this)
final class DaggerZooComponent implements ZooComponent {
@Override
public Zoo inject(Zoo zoo) {
return injectZoo(zoo);
}
private Zoo injectZoo(Zoo instance) {
// providerTigerProvider.get():这里是Tiger对象单例的关键所在
// Zoo_MembersInjector.injectTiger():真实的赋值动作在该方法中
Zoo_MembersInjector.injectTiger(instance, providerTigerProvider.get());
return instance;
}
}
providerTigerProvider.get()
The above analysisproviderTigerProvider
is anProvider
object, it holds theZooModule_ProviderTigerFactory
object, let's look at it firstProvider.get()
public final class DoubleCheck<T> implements Provider<T>, Lazy<T> {
private DoubleCheck(Provider<T> provider) {
assert provider != null;
this.provider = provider; // 该变量为ZooModule_ProviderTigerFactory对象.
}
@Override
public T get() {
Object result = instance;
if (result == UNINITIALIZED) {
synchronized (this) {
result = instance;
if (result == UNINITIALIZED) {
// 经过双重判断,如果result为null,
// 那么就调用ZooModule_ProviderTigerFactory.get()获取tiger对象赋值给result变量
result = provider.get();
instance = reentrantCheck(instance, result);
provider = null;
}
}
}
// 最终将tiger对象返回
return (T) result;
}
}
ZooModule_ProviderTigerFactory.get()
public final class ZooModule_ProviderTigerFactory implements Factory<Tiger> {
@Override
public Tiger get() {
return providerTiger(module);
}
public static Tiger providerTiger(ZooModule instance) {
// ZooModule_ProviderTigerFactory.get()最终调用的方法是 ZooModule.providerTiger(),最终返回Module创建的tiger对象.
return Preconditions.checkNotNull(instance.providerTiger(), "Cannot return null from a non-@Nullable @Provides method");
}
}
Zoo_MembersInjector.injectTiger(instance, providerTigerProvider.get())
The final assignment action is in this method
public final class Zoo_MembersInjector implements MembersInjector<Zoo> {
@InjectedFieldSignature("com.yey.dagger2.Zoo.tiger")
public static void injectTiger(Zoo instance, Object tiger) {
instance.tiger = (Tiger) tiger;
}
}
to sum up
- When
Module
added to the@Singleton
notes, less dependent on theModule
syringe have to increase@Singleton
annotations, otherwise an error. Module
Add@Singleton
annotations to the method in the current method. When the object returned by the current method is returned, the returned object will be double checked to ensure that the object is a singleton.@Singleton
The annotation is synchronized with the life cycle of each syringe.Two different syringes will actually create twotiger
objects, but under the same syringe, thetiger
object is a singleton.
Use when the syringes are interdependent@Scope
class Tiger {
public void sleep() {
System.out.println("Tiger sleeping");
}
}
@Module
class ZooModule {
// 表示Tiger对象是单例.
@Singleton
@Provides
public Tiger providerTiger() {
return new Tiger();
}
}
// ZooComponent注射器使用了@Singleton,当另外一个注射器依赖它时,也需要添加一个@Scope类型注释.
@Singleton
@Component(modules = {
ZooModule.class})
interface ZooComponent {
Tiger provider();
}
// 假如PlaygroundComponent注射器依赖ZooComponent注射器,因为ZooComponent有@Singleton注释,
// 所以PlaygroundComponent注射器也必须增加一个Scope注释,并且不允许和@Singleton注释相同,
// 那么只有自定义一个@MyScope注释
@MyScope
@Component(dependencies = {
ZooComponent.class})
interface PlaygroundComponent {
Playground inject(Playground playground);
}
//自定义一个MyScope注释
@Scope
@Documented
@Retention(RUNTIME)
public @interface MyScope {
}
In fact, the @Singleton
comments and @MyScope
functions are the same, but the names are different. In the above code, it is completely possible to swap the two of them. Within the life cycle of the same syringe, @Singleton
the object obtained by the annotation method is a singleton.