假设我们有一个名为 的类Bean
,它依赖于另一个名为 的类Service
,使用字段注入,我们无法更改这些类的代码。另一个类 ( App
) 使用 aProvider
来随时构造 Bean 的新实例,我们可以随意更改这些类中的代码。
由于在Provider
'get()
方法中,新实例是使用new
运算符创建的,因此无法将 注入Service
到 中Bean
,因此该Bean
实例将不完整(服务字段将为null
)。
绕过该问题的一种方法是将Injector
Provider 注入并在新实例上调用injector.injectMembers()
该方法。get()
下面是一个代码示例(我避免使用接口来缩短代码)。
class Bean {
@Inject private Service service;
public Bean() {
}
public void bar() {
this.service.foo();
}
}
class Service {
public void foo() {
System.out.println("foo");
}
}
class App {
@Inject private Provider<Bean> beanProvider;
public App() {
}
public void run() {
this.beanProvider.get().bar();
}
}
class BeanProvider implements Provider<Bean> {
@Inject Injector injector;
public Bean get() {
Bean mybean = new Bean();
this.injector.injectMembers(mybean);
return mybean;
}
}
// A simple module to bind the classes
class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(Service.class);
bind(Bean.class).toProvider(BeanProvider.class);
bind(App.class);
}
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new MyModule());
injector.getInstance(App.class).run();
}
另一种方法是将 Bean 更改为使用构造注入,但正如我所说,让我们假设我们不能这样做。
我知道大多数人声称Injector
应该避免注入,因为它破坏了整个 DI 理念,因为注入器只能在应用程序的入口点使用,而不能在其他任何地方使用,但是由于 Guice 提供了在应用程序中使用 DI 的不同方法,例如Field Injection,可能会发生像我描述的那种情况。此外,我已经看到在几个项目中经常使用 Field Injection,因此这种情况经常出现。
那么,是否有一种“更清洁”的方法来避免注入Injector
我描述的问题?