使用guice时如何避免使用injector.createInstance()?

时间:2010-10-21 11:20:08

标签: dependency-injection guice

根据我到目前为止所读到的内容,根据我刚才读到的内容,我应该只在我的引导类中使用Injector(在独立的应用程序中,这通常是在主要的( )方法),如下面的例子(取自guice文档):

public static void main(String[] args) {
    /*
     * Guice.createInjector() takes your Modules, and returns a new Injector
     * instance. Most applications will call this method exactly once, in their
     * main() method.
     */
    Injector injector = Guice.createInjector(new BillingModule());

    /*
     * Now that we've got the injector, we can build objects.
     */
    RealBillingService billingService = injector.getInstance(RealBillingService.class);
    ...
  }

但是,如果不是我需要的所有对象都可以在启动期间创建?也许我想在应用程序运行时响应一些用户交互?我不必将我的注入器保持在某处(例如作为静态变量),然后在需要创建新对象时调用injector.getInstance(SomeInterface.class)吗?

当然,在整个地方传播对Injector.getInstance()的调用似乎并不可取。

我在这里弄错了什么?

3 个答案:

答案 0 :(得分:13)

是的,你基本上只应该使用Injector来创建获取root-object的实例。应用程序的其余部分不应触及Guice-Container。正如您所注意到的,您仍需要在需要时创建一些对象。有不同的方法可以做到这一点,每种方法都适合不同的需求。

注入提供商 Provider是Guice的界面。它允许您请求对象的新实例。该对象将使用Guice创建。例如。

 class MyService{
     private Provider<Transaction> transactionProvider;
     public MainGui(Provider<Transaction> transactionProvider){
         this.transactionProvider = transactionProvider;
     }

     public void actionStarted(){
         Transaction transaction = transactionProvider.get();
     }

建立工厂 通常你需要某种工厂。该工厂使用一些注入的服务和一些参数,并为您创建一个新对象。然后,您将此工厂用于新实例。然后你注入那个工厂并使用它。使用AssistedInject - 扩展名

也可以提供帮助

我认为有了这两种可能性,你很少需要使用Guice-Injector本身。然而,有时仍然适合使用注射器本身。然后,您可以将Injector注入组件。

答案 1 :(得分:3)

要扩展Gamlor发布的答案,您还需要区分您正在使用的对象类型。

对于服务,注入是正确的解决方案,但是,不要试图始终使数据对象(通常是对象图中的叶子)可注入。在某些情况下,这是正确的解决方案,但注入Provider<List>可能不是一个好主意。我的一位同事最终做到了这一点,它使代码库在一段时间后非常混乱。我们刚刚完成清理工作,Guice模块现在更加具体。

答案 2 :(得分:0)

在摘要中,我认为一般的想法是,如果响应用户事件是应用程序功能的一部分,那么,那么......

BillingService billingService = injector.getInstance(BillingService.class);
billingService.respondToUserEvent( event );

我想这可能有点抽象,但基本的想法是你从Guice得到你的顶级应用程序类。从您的问题来看,我想BillingService可能不是您的顶级课程吗?