フィールド インジェクションを使用してBean
という別のクラスに依存する というクラスがあり、これらのクラスのコードを変更できないとします。別のクラス ( ) は、いつでも Bean の新しいインスタンスを構築するために を使用します。これらのクラスのコードは自由に変更できます。Service
App
Provider
のメソッドProvider
では、演算子get()
を使用して新しいインスタンスが作成されるため、 を に注入することはできません。そのため、インスタンスは不完全になります (サービス フィールドは になります)。new
Service
Bean
Bean
null
この問題を回避する 1 つの方法Injector
は、プロバイダーにを挿入し、新しいインスタンスでメソッド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();
}
もう 1 つの方法は、コンストラクション インジェクションを使用するように Bean を変更することですが、前述したように、それができないと仮定しましょう。
ほとんどの人Injector
は、インジェクターはアプリケーションのエントリ ポイントでのみ使用し、それ以外の場所では使用しないため、DI の哲学全体を壊すため、避けるべきだと主張していますが、Guice はアプリで DI を使用するさまざまな方法を提供しているため、フィールド インジェクションなど、私が説明したような状況が発生する可能性があります。また、いくつかのプロジェクトでフィールド インジェクションがかなり頻繁に使用されているのを見てきました。
Injector
それで、私が説明した問題に注入するのを避けるための「よりクリーンな」方法はありますか?