Java 在Guice injector内部运行,@Injects在`new`-ed类上不受尊重

Java 在Guice injector内部运行,@Injects在`new`-ed类上不受尊重,java,debugging,guice,Java,Debugging,Guice,我们有一个Swing应用程序,我们希望在使用Guice-3.0时添加一点依赖注入。我们的理由是把我们的老工厂迁移到更灵活的地方 我已经确保应用程序在一个注入器内运行,现在我们希望有一个类向下运行,并有一些字段@Inject'ed,在我未经训练的眼睛看来,当“new”运行时,这个类上的@Inject注释被忽略 现在的问题是,我是否正确理解了当第一次在Guice注入器中运行时新创建的类保证它们的@Inject注释得到尊重,或者在代码中出现一个或多个新的类之后,这个属性是否丢失了 换言之: 给定A从G

我们有一个Swing应用程序,我们希望在使用Guice-3.0时添加一点依赖注入。我们的理由是把我们的老工厂迁移到更灵活的地方

我已经确保应用程序在一个注入器内运行,现在我们希望有一个类向下运行,并有一些字段@Inject'ed,在我未经训练的眼睛看来,当“new”运行时,这个类上的@Inject注释被忽略

现在的问题是,我是否正确理解了当第一次在Guice注入器中运行时新创建的类保证它们的@Inject注释得到尊重,或者在代码中出现一个或多个新的类之后,这个属性是否丢失了

换言之:

给定A从Guice获取B的一个实例,然后B创建
新的C()
,然后运行
新的D()
,而D恰好有@Inject的内部,D应该由Guice处理吗?

如果是,我如何向Guice配置中添加代码,使我能够看到Guice正在处理“new X()”,并且正在执行“@Inject setY(Y)”呢?我不介意此日志是否非常大-我只需要验证Guice是否按预期工作。

否,Guice不会直接处理使用
new
创建的任何内容。。。它不会变魔术。Guice的工作方式是为您创建对象图。您不应该在类中引用
Injector
,也不应该使用
new
创建您想要注入的服务

以下是您可能拥有的一些选项:

  • C
    注入
    B
    而不是
    new
    ing它。将
    D
    注入
    C
  • 如果您需要在当前正在添加它们的类中多次创建它们中的一个或两个,请插入
    Provider
    Provider
    ,并使用
    get()
    而不是
    new
  • 如果只有在运行时可用的对象需要传递给这些类(例如,基于用户输入或其他地方的数据)来创建它们,那么您可能需要使用辅助注入并注入
    CFactory
    DFactory
    ,而不是
    提供程序
  • 如果真的找不到更好的方法,可以使用
    injector.injectMembers(Object)
    来注入用
    new
    创建的对象。。。但是如果你这么做的话,很难说Guice是否帮了你很多
否,使用
new
直接创建的任何内容都不会由Guice处理。。。它不会变魔术。Guice的工作方式是为您创建对象图。您不应该在类中引用
Injector
,也不应该使用
new
创建您想要注入的服务

以下是您可能拥有的一些选项:

  • C
    注入
    B
    而不是
    new
    ing它。将
    D
    注入
    C
  • 如果您需要在当前正在添加它们的类中多次创建它们中的一个或两个,请插入
    Provider
    Provider
    ,并使用
    get()
    而不是
    new
  • 如果只有在运行时可用的对象需要传递给这些类(例如,基于用户输入或其他地方的数据)来创建它们,那么您可能需要使用辅助注入并注入
    CFactory
    DFactory
    ,而不是
    提供程序
  • 如果真的找不到更好的方法,可以使用
    injector.injectMembers(Object)
    来注入用
    new
    创建的对象。。。但是如果你这么做的话,很难说Guice是否帮了你很多

    • 正如科林指出的,在您的示例中,D不是由Guice创建的。对对象调用new将在Guice DI的外部构造它。如果要确认正在通过Guice创建某些内容,可以向@Inject setter方法添加日志记录,或者如果正在进行构造函数注入,则可以添加一个新方法,仅用于日志记录目的:

      @Inject
      public void log() {
          logger.debug(//check if injected classes have been set)
          ...
      }
      
      在将一个大型Swing应用程序转换为使用Guice并从头编写了一个新应用程序之后,有一些事情需要记住

      1) Guice不是为桌面应用程序设计的。它是为在服务器上使用而创建的。启动时间并没有被考虑在内。在将Swing应用程序从所有静态工厂完全转换为所有GUI之后,根据启动是冷启动还是热启动,它在启动时间上增加了约30/60秒

      2) 仅仅添加一些图形是非常困难的。正如您现在发现的那样,您很快就会想要对一个构建的类有三个层次的依赖关系,要么必须将其全部转换为Guice,要么开始通过构造函数传递大量类并添加getter

      3) 当心急切地用Guice创建对象@默认情况下,Singleton在启动时急切地构造对象。这可能会对应用程序的启动时间造成灾难性影响。如果你对此感到担忧,Guice论坛上有一个很好的帖子,是关于创建一个@eangersingleton或@lazysingletto的,你可能想看看


      4) 尽管如此,Guice还是非常棒的,只是需要知道它是如何在桌面应用程序中获得良好性能的,正如ColinD指出的,在您的示例中,D不是由Guice创建的。对对象调用new将在Guice DI的外部构造它。如果要确认正在通过Guice创建某些内容,可以向@Inject setter方法添加日志记录,或者如果正在进行构造函数注入,则可以添加一个新方法,仅用于日志记录目的:

      @Inject
      public void log() {
          logger.debug(//check if injected classes have been set)
          ...
      }
      
      已经将一个大型Swing应用程序转换为使用Guice,并从底层编写了一个新的应用程序