我有一个这样的课程,我在我的代码中创建了自己的地方:
class StarryEyes {
@Inject MyValidator validator;
public StarryEyes(String name) {
//..
}
public doSomething() {
// validator is NULL
}
}
我希望Guice注入一个验证器实例,它有一个@Singleton注释。 我有一个在启动时加载的模块,它包含以下行:
bind(MyValidator.class);
然而,它似乎不起作用,因为“验证器”始终为空。我尝试了很多变体,如:
bind(MyValidator.class)toInstance(new MyValidator());
或类似的其他事情。这不是Guice应该如何运作的吗?
答案 0 :(得分:33)
通常Guice需要创建注入它们的对象。如果你只是打电话给new StarryEyes(name)
,Guice永远不会看到那个对象,所以它无法注入它。您可以做的一件事是在创建对象后调用injector.injectMembers(obj)
。但是,我不建议您这样做,因为您应该避免在代码中引用注入器。
你真正想要的是Assisted Inject。使用Assisted Inject,您可以为您的类声明构造函数:
@Inject public StarryEyes(MyValidator validator, @Assisted String name)
这意味着validator
是Guice应该注入的参数,而name
必须是“辅助”(即,在创建实例时提供)。
然后创建一个这样的界面:
public interface StarryEyesFactory {
StarryEyes create(String name);
}
通过Assisted Inject,Guice可以为您实现该工厂。你像这样绑定它:
bind(StarryEyesFactory.class).toProvider(
FactoryProvider.newFactory(StarryEyesFactory.class, StarryEyes.class));
然后,您可以在任何想要创建其实例的地方注入StarryEyesFactory
。您之前呼叫new StarryEyes(name)
的地方,现在请拨打starryEyesFactory.create(name)
。当您在工厂中调用create(name)
时,它将获取名称并将其传递给构造函数并提供绑定的验证器本身。
从Guice 3开始,您使用FactoryModuleBuilder执行此操作:
install(new FactoryModuleBuilder().build(StarryEyesFactory.class));