我不确定我是否完全理解依赖注入背后的想法,特别是使用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
所做的那样。
答案 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。但这有点不那么分离了。