使用guice注入对象

时间:2012-09-04 10:07:27

标签: java guice

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

我有很大的摇摆应用程序,我想引入guice,来解耦这个应用程序。 假设我在主类中有注射器

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

它有效。如果我有一些字段,让我们说在应用程序类中的JPanel,用@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);
          }

}

我的问题是,我是否需要控制注射的所有注射物体。 我无法打破控制,就像我对otherPanel所做的那样。

2 个答案:

答案 0 :(得分:5)

在Dependency Injection范例中,所有注入的对象必须控制注入容器 ,这是容器实际注入对象实例的唯一方法注入点@Inject注释)。

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

所以,回答几句话:是的,如果你想让它们自动注入,你需要让所有对象都在容器的控制下(Guice)。任何你可能会按照你在问题中的意思进行注射的黑客攻击都会破坏Inversion of Control的规则。

答案 1 :(得分:0)

如果您想要或必须使用新的,您可以使用提供商guice providers或 按需注射guice injections。 `Injector injector = 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);
      }

}

由于您注入了两个不同的面板,您可以通过命名来区分它们,即将它们与带注释的面板绑定

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

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