Guice绑定提供程序不用于依赖项实现

时间:2012-03-15 19:38:47

标签: java dependency-injection guice guice-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) No implementation for com.google.common.cache.CacheBuilder
annotated with @com.google.inject.name.Named(value=MyCacheBuilder) was bound.

我还在类和构造函数声明中尝试了原始类型和泛型类型引用的各种组合,但没有取得额外的成功。

我可以通过简单地创建提供程序并绑定从get()自己返回的实例来解决这个问题,但我希望(并且deisre)Guice会为我做这件事。

我的设置是否有些巧妙(或明显)错误?

1 个答案:

答案 0 :(得分:2)

这可能有效:

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

这里的魔法是TypeLiteral类,你应该阅读Javadoc documentation。基本上,它是一种允许您绑定到泛型类型(CacheBuilder<Object, Object>在您的情况下)的方法。这种魔力是必要的,因为Java使用擦除来实现泛型,所以你不能只写CacheBuilder<Object, Object>.class