三 Dagger2的@Singleton注解

概述:在Dagger2中,@Singleton注解可以保证被注解的对象全局都是单例。本篇主要分析为什么这个注解会有这种效果。

首先@Singleton注解需要在两处添加:
第一处是在创建实例的地方添加

@Module
public class MainModule {


    @Provides
    @Singleton
    static Student provideStudent(){
        return new Student();
    }


    @Provides
    static Teacher provideTeacher(){
        return new Teacher();
    }

}

之所以写了一个provideTeacher是为了待会做对比。

第二处需要在Component添加:

@Singleton
@Component(modules = MainModule.class)
public interface MainComponent {
    void inject(MainActivity activity);
}

添加完之后编译下,我们来看看生成的类文件有什么变化。
仔细对比会发现,主要的变化在DaggerMainComponent类里面:

 private MainActivity injectMainActivity(MainActivity instance) {
    MainActivity_MembersInjector.injectStudent(instance, provideStudentProvider.get());
    MainActivity_MembersInjector.injectStudent1(instance, provideStudentProvider.get());
    MainActivity_MembersInjector.injectTeacher(
        instance, MainModule_ProvideTeacherFactory.proxyProvideTeacher());
    MainActivity_MembersInjector.injectTeacher1(
        instance, MainModule_ProvideTeacherFactory.proxyProvideTeacher());
    return instance;
  }

Student类添加了@Singleton注解,而Teacher类没有。不同之处在于,Student实例对象是通过provideStudentProvider.get()获得的。而Teacher实例直接通过编译出来的工厂类创建。从这里其实可以分析下,这个provideStudentProvider一定是对新生成的对象做了单例处理。
果不其然:

@SuppressWarnings("unchecked")
  private void initialize(final Builder builder) {
    this.provideStudentProvider = DoubleCheck.provider(MainModule_ProvideStudentFactory.create());
  }

这个provideStudentProvider ,是通过DoubleCheck对Student的工厂类进行了包装之后得到的,那么它调用的get方法其实是DoubleCheck里面的get方法,继续点击去看一下:

//这里对返回的对象做了单例的处理
  @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;
  }

由此可以得出结论,添加了@Singleton注解之后,会有DoubleCheck这个类去做处理。这样就保证了每次获取的对象的唯一性。

你可能感兴趣的:(三 Dagger2的@Singleton注解)