我有一个用例,似乎从多个位置引用Guice注入器是唯一的解决方案 - 尽管通常不鼓励这样做。
我的应用程序建立在开源ETL平台Talend之上。我的大多数实际应用程序都是由Talend组件调用的Java类。这些组件包括我编写的Java片段,反过来,它实例化/调用我的类。
现在我打算在整个Java类中使用Guice,但是我绝对没有办法将依赖项注入到Talend组件中(因此它们可供Java代码段使用)。相反,我需要实际创建这些依赖项。我想至少让Guice控制实例化,这意味着我可以调用我的类(具有new
构造函数的类)的唯一方法,而不是使用@Inject
。 injector.getInstance
。反过来,这意味着我需要保持注射器周围,大概是使用一个老式的工厂,它首先创建它并使其作为单身人士使用。
我只是看不到任何其他方法来处理这个问题,但也许我错过了一些东西。
答案 0 :(得分:3)
考虑static injection。这仍将隐藏您的应用程序中对您的注入器的持久引用,但它将使您不必通过injector.getInstance(...)
调用来查看代码。无论如何,如果你真的需要,你可以注入Injector
。
class TalendDependencyModule extends AbstractModule {
@Override public void configure() {
requestStaticInjection(ExtractorDependencies.class);
requestStaticInjection(ProcessorDependencies.class);
}
}
public class ExtractorDependencies {
@Inject private static Provider<ParserService> parserServiceProvider;
@Inject private static Provider<SomethingElse> somethingElseProvider;
private ExtractorDependencies() { }
static ParserService getParserService() {
return parserServiceProvider.get();
}
/* ... */
}
答案 1 :(得分:0)
我不知道您有多少个Talend对象,但您可能需要考虑使用提供程序。例如,假设您有自己的类,希望Guice管理创建:
public interface INotTalendControlled {}
public class NotTalendControlled implements INotTalendControlled {}
这将被添加到Talend对象中,该对象的依赖关系不能通过Guice注入(尽管我假设有一些手动过程,无论是构造函数还是setter):
public class TalendControlled {
private INotTalendControlled notTalendControlled;
private TalendControlled(INotTalendControlled notTalendControlled) {
this.notTalendControlled = notTalendControlled;
}
public INotTalendControlled getValue() {
return notTalendControlled;
}
}
如果您希望Guice管理这些生命周期和Talend控制对象的生命周期,您可以使用这样的提供程序:
public static class TestModule extends AbstractModule {
@Override
protected void configure() {
bind(INotTalendControlled.class).to(NotTalendControlled.class);
}
@Provides
public TalendControlled provideInjectsToTalendObject(INotTalendControlled notTalendControlled) {
return new TalendControlled(notTalendControlled);
}
}
@Provides方法将隐藏所有对象的new使用,因为您现在可以直接注入TalendControlled对象(@Inject TalenControlled talendControlled),并且不需要显式注入器来构造它们的依赖项。