(十) Dagger2 懒加载案例分析

代码示例
class Tiger {
    public void sleep() {
        System.out.println("Tiger sleeping");
    }
}
@Module
class ZooModule {
    @Provides
    public Tiger providerTiger() {
        return new Tiger();
    }
}
@Component(modules = {ZooModule.class})
interface ZooComponent {
    Zoo inject(Zoo zoo);
}
public class Zoo {
    @Inject
    Lazy<Tiger> tigerLazy;
    @Inject
    Provider<Tiger> tigerProvider;
    @Test
    public void 案例十() {
        DaggerZooComponent.create().inject(this);
        // 在调用get的时候才会真的去创建一个tiager对象,这个就是懒加载.
        tigerLazy.get().sleep();
        tigerProvider.get().sleep();
    }
}
Dagger2生成代码阅读

主要分析懒加载的流程逻辑.

就着上面的案例来看下Degger2生成的代码,生成的代码在build\generated\sources\annotationProcessor\..文件夹中.

  • 当调用.inject(this)时,最终调用的代码如下:
final class DaggerZooComponent implements ZooComponent {
    private Provider<Tiger> providerTigerProvider;
    private DaggerZooComponent(ZooModule zooModuleParam) {
      initialize(zooModuleParam);
    }

    @SuppressWarnings("unchecked")
    private void initialize(final ZooModule zooModuleParam) {
        // 创建ZooModule_ProviderTigerFactory工厂对象,它的父类是Provider.
        this.providerTigerProvider = ZooModule_ProviderTigerFactory.create(zooModuleParam);
    }
    @Override
    public Zoo inject(Zoo zoo) {
        return injectZoo(zoo);
    }
   private Zoo injectZoo(Zoo instance) {
        // DoubleCheck.lazy(providerTigerProvider):这个是创建一个DoubleCheck对象,该对象的父类有Provider与Lazy.该对象持有providerTigerProvider对象.
        Zoo_MembersInjector.injectTigerLazy(instance, DoubleCheck.lazy(providerTigerProvider));
        // 这一步是为容器也就是Zoo对象中的tigerProvider字段赋值.
        Zoo_MembersInjector.injectTigerProvider(instance, providerTigerProvider);
        return instance;
   } 
}
  • 看下DoubleCheck.lazy(providerTigerProvider)
public final class DoubleCheck<T> implements Provider<T>, Lazy<T> {
    public static <P extends Provider<T>, T> Lazy<T> lazy(P provider) {
      if (provider instanceof Lazy) {
        @SuppressWarnings("unchecked")
        final Lazy<T> lazy = (Lazy<T>) provider;
        ...
        return lazy;
      }
      // 创建DoubleCheck对象.
      return new DoubleCheck<T>(checkNotNull(provider));
    }
}
  • 在容器中使用tigerProvider.get()方法最后调用的是ZooModule_ProviderTigerFactory.get()
public final class ZooModule_ProviderTigerFactory implements Factory<Tiger> {
    @Override
    public Tiger get() {
      return providerTiger(module);
    }
    public static Tiger providerTiger(ZooModule instance) {
      // instance.providerTiger():到这一步才开始使用`ZooModule.providerTiger()`创建对象.
      // 从该方法也可以看出,当每调用一次get(),都会生成一个新的Tiger对象
      return Preconditions.checkNotNull(instance.providerTiger(), "Cannot return null from a non-@Nullable @Provides method");
    }
}
  • 在容器中使用tigerLazy.get()方法最后调用的是DoubleCheck.get()
public final class DoubleCheck<T> implements Provider<T>, Lazy<T> {
    // 很明显该方法是用来获取单例对象的.所以,当每次调用tigerLazy.get()返回的是一个单例对象.
    @Override
    public T get() {
      Object result = instance;
      if (result == UNINITIALIZED) {
        synchronized (this) {
          result = instance;
          if (result == UNINITIALIZED) {
            // 这里是真实的使用ZooModule_ProviderTigerFactory.get()开始创建tiger对象
            result = provider.get();
            instance = reentrantCheck(instance, result);
            ...
            provider = null;
          }
        }
      }
      return (T) result;
    }
}

上面分析了,使用LazyProvider做到懒加载的内部逻辑也揭示了为何Lazy类型的对象最终获取的是一个单例对象.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章