2

我不确定我是否完全理解依赖注入背后的想法,尤其是使用 Guice。

我有相当大的摇摆应用程序,我想介绍一下 guice 来解耦这个应用程序。假设我在主课上有注射器

Guice.createInjector(new BindingModule());
Application app = injector.getInstance(Application.class);
app.run();

它有效。如果我有一些字段,比如说 JPanel,在 Application 类中,用 @Inject 注释然后它被注入。但是,如果我在 Application 构造函数中手动创建一些东西,而不是示例中的 JTree 将不会被注入(假设一切都配置正确)。

class Application {

          @Inject JPanel mainPanel //this will be injected

          JPanel otherPanel;


          public Application() {
              otherPanel = new MyNewPanel();

              mainPanel.add(otherPanel);
          }

}  

class MyNewPanel extends JPanel { 


          @Inject JTree tree;  //this will not be injected

          public MyNewPanel() {

               add(tree);
          }

}

我的问题是,我是否需要让所有注入的对象控制要注入的 guice。我无法打破控制,就像我对otherPanel.

4

2 回答 2

5

在依赖注入范式中,所有注入的对象都必须在注入容器的控制之下,这是容器实际上可以将对象实例注入注入点@Inject注解)的唯一方法。

当您使用new运算符实例化对象实例时,该对象实例不受注入容器的控制(它是由您创建的,而不是容器创建的)。因此,即使您在该新对象实例中有注入点,容器也不知道它们,因此它不能将任何注入候选注入该对象实例的注入点(因为,正如我已经说过的,它是不受其控制)。

所以,回答几句:是的,如果你想让它们被自动注入,你需要让所有对象都在容器(Guice)的控制之下。任何你可能想出的让注入按照你在问题中的意思工作的技巧都会违反Inversion of Control的规则。

于 2012-09-04T13:29:25.777 回答
0

如果您想或必须使用新的,您可以使用提供者guice 提供者或按需注入guice injections。`注射器注射器 = Guice.createInjector(...);

MyNewPanel myNewPanel = new MyNewPanel();
injector.injectMembers(myNewPanel);`

您可以稍微重写上面的代码以使用标准注入。

class Application {

      final JPanel mainPanel;

      final JPanel otherPanel;


      @Inject
      public Application( @Named("main") JPanel mainPanel, @Named("other") JPanel otherPanel) {
          this.otherPanel = otherPanel;
          this.mainPanel = mainPanel;
          mainPanel.add(otherPanel);             
      }

}  

class MyNewPanel extends JPanel { 


      @Inject JTree tree;  

      public MyNewPanel() {

           add(tree);
      }

}

由于您注入了两个不同的面板,因此您可以通过命名来区分它们,即用 annotatedWith 绑定它们

binder.bind( JPanel.class ).annotatedWith( Names.named( "other" ).to( MyNewPanel.class );

或者您在 Application 构造函数中使用 MyNewPanel。但这有点不那么解耦。

于 2012-09-04T13:20:13.787 回答