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 回答