情境:我需要在一些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并从其静态方法GuiceInjectorFactory.getInjector()
获取Injector
,当我们需要它时(例如在我们的Hibernate拦截器中)。
我有点困惑于“您不应该直接使用Injector”的建议。除了调用injector.getInstance()
或injector.injectMembers()
之外,我怎么能注入实例呢?没有别的办法。是的,您可以定义Provider方法,但除非某个地方,某些东西使用了Injector,否则这些方法将永远不会被调用。是的,有一些模块会为您使用Injector
,例如ServletModule;您必须自己创建Injector
,但之后可以交给ServletModule
处理。
因此,在某些情况下,您可以避免直接使用Injector
,但这并不意味着您“不应该”使用它。如果您仅使用Guice而没有任何可选模块,则应在许多地方使用Injector
,因为没有其他触发注入的方法。(我认为那些整天在框架内编写代码的开发人员有时会忘记有些人实际上会实例化自己的对象。)
getInstance()
。请注意,这里的翻译并未改变原意,只是将语言更加通俗易懂。 - Tim GageInjector
”这句话的重点不是在“不应该直接使用”,而是“不应该注入 Injector
”。
Guice在模块创建方面提供了很多检查,但如果模块内部最终注入了一个Injector
,那么这些检查都无法起作用。
从Guice.createInjector(...myModules)
手动创建的初始Injector
可以完全正常地使用。 - Paul Féraud正如 @gpampara 所说,Provider<T>
应该用于惰性/可选初始化。此外,就像我在回答你另一个问题时所说的那样,在几乎所有情况下,你应该避免在代码中引用 Injector
。
话虽如此,在 Guice 创建的类中,创建对象的 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的传递。
@Inject Injector injector
获取注入器,可以放在构造函数/字段/方法中。 - gpamparachildInjectors
。通常情况下,它们是不必要的,你应该只使用一个注入器。当然也有例外,但这种情况很少见。 - gpampara