2012-03-15 1 views
2

Guiceのバインドプロバイダ私は工場出荷時に予め設定されたオブジェクトを注入するために、プロバイダの注入を使用しようとしている

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インスタンスを取得するために注射器を使用し

、Iログ出力を取得せず、未構成の 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) No implementation for com.google.common.cache.CacheBuilder 
annotated with @com.google.inject.name.Named(value=MyCacheBuilder) was bound. 

私も様々な組み合わせを試してみましたクラスとコンストラクタの宣言での生の型参照とジェネリック型の参照を追加します。

プロバイダを作成してget()から返されたインスタンスをバインドするだけで、これを回避できますが、私はGuiceがそれを実行することを期待しています。

私の設定には、何か微妙な(または明らかに)間違いがありますか?

答えて

2

この仕事かもしれません:

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

魔法のビット、ここでそのJavadoc documentationあなたが読むべきTypeLiteralクラスは、あります。基本的には、一般的なタイプ(あなたの場合はCacheBuilder<Object, Object>)にバインドする方法です。この魔法は、Javaが消去を使ってジェネリックを実装するために必要です。したがって、CacheBuilder<Object, Object>.classと書くことはできません。

+0

ありがとうございます。そのトリックをした。これと普通の 'CacheBuilder.class'バインディングとの基本的な違いについていくつか説明を加えてください。 – arootbeer

+0

もう少し説明を追加しました。 –

+0

余計にありがとう。私はそれらのjavadocsを読んだことがあるが、私はその件に関するいくつかの無知を認めます。私は尋ねる前にその違いについてより多くの研究をすることができませんでした。再度、感謝します。 – arootbeer

関連する問題