我正在尝试使用提供程序注入将预配置的对象注入工厂:
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能够为我做到这一点。我的设置有什么微妙(或显然)的问题吗?
最佳答案
这可能起作用:
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
。