【问题标题】:Injecting object using guice使用 guice 注入对象
【发布时间】:2012-09-04 10:07:26
【问题描述】:

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

我有一个相当大的 Swing 应用程序,我想介绍一下 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所做的那样。

【问题讨论】:

    标签: java guice


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      如果您想或必须使用新的,您可以使用提供者guice providers 或 按需注入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。但这有点不那么解耦。

      【讨论】:

        猜你喜欢
        • 2013-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多