3

プロバイダーインジェクションを使用して、事前構成されたオブジェクトをファクトリにインジェクトしようとしています。

public class CacheBuilderProvider 
    implements Provider<CacheBuilder<Object, Object>> {
    public CacheBuilder<Object, Object> get () {
        //Log the cache builder parameters before creation

        CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder();
        //configure the cacheBuilder
        return cacheBuilder;
    }
}

public class MyCacheFactory {
    private final CacheBuilder<Object, Object> cacheBuilder;

    @Inject
    public MyFactory(CacheBuilder<Object, Object> cacheBuilder) {
        this.cacheBuilder = cacheBuilder;
    }
}

public class CacheModule extends AbstractModule {            
    @Override
    protected void configure() {
        bind(CacheBuilder.class)
            .toProvider(CacheBuilderProvider.class)
            .in(Singleton.class);
        bind(MyCacheFactory.class)
            .in(Singleton.class);
    }
}

インジェクターを使用してMyCacheFactoryインスタンスを取得すると、ログ出力が表示されず、未構成のCacheBuilder<Object, Object>インスタンスが表示されます。私の構成はどれも適用されていません。ブレークポイントを設定すると、プロバイダーが使用されていないことが確認されます。

私はまた@Named("MyCacheBuilder")、適切な部分に適用しようとしました:

public class CacheBuilderProvider 
    implements Provider<CacheBuilder<Object, Object>> {
    @Named("MyCacheBuilder")
    public CacheBuilder<Object, Object> get () { //... }
}

public class MyCacheFactory {
    //...

    @Inject
    public MyFactory(
        @Named("MyCacheBuilder") 
        CacheBuilder<Object, Object> cacheBuilder
    ) {
        //... 
    }
}

このコードを実行しようとすると、次のようになりますCreationException

1)com.google.common.cache.CacheBuilderの実装はありません
@ com.google.inject.name.Named(value = MyCacheBuilder)で注釈が付けられました。

また、クラス宣言とコンストラクター宣言で生の型参照とジェネリック型参照のさまざまな組み合わせを試しましたが、それ以上の成功はありませんでした。

プロバイダーを作成し、自分から返されたインスタンスをバインドするだけでこれを回避できますがget()、Guiceが私に代わってそれを行うことを期待しています(そして望んでいます)。

私の設定に微妙に(または明らかに)何か問題がありますか?

4

1 に答える 1

3

これはうまくいくかもしれません:

bind(new TypeLiteral<CacheBuilder<Object, Object>>() {})
          .annotatedWith(Names.named("MyCacheBuilder"))
          .toProvider(CacheBuilderProvider.class)
          .in(Singleton.class);

ここでのちょっとした魔法はTypeLiteralクラスであり、そのJavadoc ドキュメントを読む必要があります。基本的には、ジェネリック型にバインドできるようにする方法です(CacheBuilder<Object, Object>あなたの場合)。Javaは消去を使用してジェネリックを実装しているため、この魔法が必要ですCacheBuilder<Object, Object>.class

于 2012-03-15T20:52:22.113 に答える