2012-09-04 160 views
2

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

我有相当大的swing应用程序,我想介绍guice来解耦这个应用程序。 假设我有喷射器主类

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

和它的作品。如果我有一些字段,比如JPanel,在Application类中,用@Inject注释,然后注入它。但是如果我在应用程序构造函数 中手动创建一些比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做的那样。

回答

0

如果你想要或必须使用新的,你可以使用供应商guice providers或 onmand和注入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); 

绑定它们或者你在应用程序构造函数中使用MyNewPanel。但是这种联系稍微有些分离。

4

在依赖注入范例,所有注入的对象必须在注入容器的控制,这是该容器实际上可以注入一个对象的一个​​实例为注入点@Inject注释)的唯一方式。

当实例化使用new操作对象实例,然后该对象实例是从注射容器的控制的(它是由所创建,而不是容器)。因此,即使在新对象实例中有注入点,容器也不会注意到它们,因此它不能将任何注入候选注入该对象实例的注入点(因为,正如我已经说过的那样,它是脱离其控制)。

因此,用几句话回答:是的,如果您希望自动注入它们,您需要将所有对象都放在容器(Guice)的控制下。任何你可能想出来的注入方式在你的问题中按照你的意思进行操作将破坏Inversion of Control的规则。