匕首2延迟初始化地图条目

问题描述

我有一个Dagger模块和定义如下的组件。我只想在从地图中获取资源时在模块中创建资源,而不是在服务启动时在模块中创建资源。我玩过Lazy,但不确定如何实现。

@Module
public abstract class ExpensiveObjectModule {

    @Singleton
    @Provides
    @IntoMap
    @UniqueKey(Key.A)
    static ExpensiveObject provideKeyAExpensiveObject() {
        return new ExpensiveObject(Key.A);
    }

    @Singleton
    @Provides
    @IntoMap
    @UniqueKey(Key.B)
    static ExpensiveObject provideKeyBExpensiveObject() {
        return new ExpensiveObject(Key.B);
    }
}
@Singleton
@Component (modules = {
        ExpensiveObjectModule.class
})
public interface HandlerComponent {
    Map<Key,ExpensiveObject> getExpensiveObjectByKey();

}
handlerComponent.getExpensiveObjectByKey().get(key);

解决方法

每当您可以注入A时,您也可以注入Provider<A>,因此可以拥有Map<K,A>来代替Map<K,Provider<A>>。 Lazy可能也可以使用相同的方法,但是Provider会尊重任何东西,而Lazy会始终对其进行缓存。

所以您可以像这样返回地图:

Map<Key,Provider<ExpensiveObject>> getExpensiveObjectByKey();

一个最小的示例(但在Kotlin中)如下所示:

@MustBeDocumented
@Target(
    AnnotationTarget.FUNCTION,AnnotationTarget.PROPERTY_GETTER,AnnotationTarget.PROPERTY_SETTER
)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class Key(val value: String)

@Module
object ModFoo {

    @Provides
    @IntoMap
    @Key("foo")
    fun foo(): Any = "Foo"

    @Provides
    @IntoMap
    @Key("bar")
    fun bar(): Any = 3
}

@Component(modules = [ModFoo::class])
interface Foo {
    val foo: Map<String,Any>
    val fooProviders: Map<String,Provider<Any>>
}