假设我们有一个名为 Bean
的类,它依赖于另一个名为 Service
的类,使用 Fields Injection 和 我们不能更改这些类的代码。另一个类 (App
) 使用 Provider
以便在需要时构造 Bean 的新实例,我们可以自由更改这些类中的代码。
由于在 Provider
的 get()
方法中,新实例是使用 new
运算符创建的,因此不可能注入(inject) Service
到 Bean
中,因此 Bean
实例将不完整(Service 字段将为 null
)。
绕过该问题的一种方法是在 Provider 中注入(inject) Injector
并在 get()
中调用 injector.injectMembers()
> 方法,在新实例上。
代码示例如下(我避免使用接口(interface)来缩短代码)。
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 更改为使用构造注入(inject),但正如我所说,让我们假设我们不能那样做。
我知道大多数人声称应该避免注入(inject) Injector
,因为它打破了整个 DI 哲学,因为注入(inject)器应该只在应用程序的入口点而不是其他地方使用,但是因为Guice 提供了在应用程序中使用 DI 的不同方式,例如 Field Injection,可能会出现我描述的情况。此外,我已经看到在多个项目中经常使用字段注入(inject),因此经常会出现这种情况。
那么,是否有一种“更干净”的方法来避免在我描述的问题中注入(inject) Injector
?
最佳答案
这看起来应该不是您的模块的问题。看起来您根本不需要创建提供程序。
您在模块中设置的绑定(bind)应该会导致 Service 在您需要的任何地方注入(inject)到 Bean 中。因此,您应该能够用 Bean 注入(inject)替换 App 中的提供者声明。
class App {
@Inject private Bean beanObject;
public App() {
}
public void run() {
this.beanObject.bar();
}
}
// A simple module to bind the classes
class MyModule extends AbstractModule {
@Override
protected void configure() {
//bind this to whatever you want to inject into Bean...
bind(Service.class);
bind(Bean.class);
bind(App.class);
}
}
如果这对您不起作用,您能否说明您正在尝试做什么以及为什么需要提供商?
关于java - Guice - 字段注入(inject)限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22364274/