情况:我需要一些惰性依赖实例化FooClass
,所以我Injector
作为构造函数参数传递给类。
private final Injector m_injector;
public FooClass(@Named("FooInjector") Injector injector) {
m_injector = injector;
}
但是 guice 不允许绑定核心类(注入器、模块等)。解决办法是什么?
情况:我需要一些惰性依赖实例化FooClass
,所以我Injector
作为构造函数参数传递给类。
private final Injector m_injector;
public FooClass(@Named("FooInjector") Injector injector) {
m_injector = injector;
}
但是 guice 不允许绑定核心类(注入器、模块等)。解决办法是什么?
你不应该Injector
直接使用。而是通过Provider<FooClass>
。此外,您应该在使用的地方注入提供程序FooClass
。
private final Provider<FooClass> provider;
@Inject
public ClassWhereFooIsUsed(Provider<FooClass> provider) {
this.provider = provider;
}
.... somewhere else
FooClass f = provider.get(); // This is lazy
正如其他人已经回答的那样,您可以简单地使用@Inject Injector
,因为 Guice 定义了绑定本身。
通常Injector
,您的应用程序中只需要一个,静态变量是一种比注入它更容易存储和访问单例的方法。在我们的 Web 应用程序中,我们使用stripes-guicer并在需要时Injector
从它的静态方法中获取GuiceInjectorFactory.getInjector()
它(例如,在我们的 Hibernate 拦截器中)。
我对“您不应该直接使用 Injector”的建议感到有些困惑。injector.getInstance()
除了调用or之外,我还能如何获得注入实例injector.injectMembers()
?没有办法。是的,您可以定义 Provider 方法,但它们永远不会被调用,除非某处使用 Injector。是的,有些模块Injector
像ServletModule一样为您使用;你必须自己创造Injector
,但你可以把它留给ServletModule
之后。
所以在某些情况下,你可以避免Injector
直接使用,但这并不意味着你“不应该”使用它。如果您在没有任何可选模块的情况下单独使用 Guice,那么您“应该”在Injector
所有地方都使用 Guice,因为没有其他方法可以触发注入。(我认为整天在框架内编写代码的开发人员有时会忘记有些人实际上实例化了他们自己的对象。)
正如@gpampara 所说,Provider<T>
应该用于延迟/可选初始化。此外,正如我在回答您的其他问题时所说,您应该Injector
在几乎所有情况下避免在代码中引用。
也就是说,在 Guice 创建的类中,Injector
创建对象的对象可以通过声明对Injector
. Injector
无需声明任何绑定即可自动用于注入。
如果你确实注入了Injector
,你应该想想你为什么要这样做。为什么不直接声明对类所依赖的实际接口/类的依赖关系?向构造函数添加新的依赖项就像通过代码中的其他地方检索某个依赖项的实例一样容易Injector
,并且它也使代码更易于理解。
您可能不应该注入实例的参数Injector
是非常有效的,但与任何规则一样,也有例外。
我有一个工厂类,它接受需要为其提供实例的类引用。这些实例不一定是已知的(实际上,它们是,但有很多而且可能更多)所以我不能为所有这些创建提供者。
public class ThingFactory {
private Injector injector;
@Inject
ThingFactory(Injector injector) {
this.injector = injector;
}
public <T> T getInstance(Class<T> aClass) {
return injector.getInstance(aClass);
}
}
我的应用程序中真正的类是扩展和覆盖另一个类——这就是为什么这个类基本上是 Guice 的传递。