(8) Dagger2 @Singleton case analysis

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 @Singletonannotated, the Tigerobject 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.

  1. 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);
        }
    }
}
  1. 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;
    }
}
  1. .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;
    }
}
  1. providerTigerProvider.get()
    The above analysis providerTigerProvideris an Providerobject, it holds the ZooModule_ProviderTigerFactoryobject, 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;
    }
}
  1. 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");
    }
}
  1. 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
  1. When Moduleadded to the @Singletonnotes, less dependent on the Modulesyringe have to increase @Singletonannotations, otherwise an error.
  2. ModuleAdd @Singletonannotations 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.
  3. @SingletonThe annotation is synchronized with the life cycle of each syringe.Two different syringes will actually create two tigerobjects, but under the same syringe, the tigerobject 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 @Singletoncomments and @MyScopefunctions 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, @Singletonthe object obtained by the annotation method is a singleton.

Guess you like

Origin blog.csdn.net/MoLiao2046/article/details/106884526