Google guiceを使用して、アプリケーションのすべてのクラスでプロパティを使用できるようにしたい。プロパティファイルをロードしてバインドするモジュールを定義しましたTest.properties。
Property1=TEST
Property2=25
パッケージcom.test;
import Java.io.FileNotFoundException;
import Java.io.FileReader;
import Java.io.IOException;
import Java.util.Properties;
import com.google.inject.AbstractModule;
import com.google.inject.name.Names;
public class TestConfiguration extends AbstractModule {
@Override
protected void configure() {
Properties properties = new Properties();
try {
properties.load(new FileReader("Test.properties"));
Names.bindProperties(binder(), properties);
} catch (FileNotFoundException e) {
System.out.println("The configuration file Test.properties can not be found");
} catch (IOException e) {
System.out.println("I/O Exception during loading configuration");
}
}
}
プロパティを注入するインジェクターを作成するメインクラスを使用しています。
package com.test;
import com.google.inject.Guice;
import com.google.inject.Injector;
public class Test {
public static void main(String[] args) {
TestConfiguration config = new TestConfiguration();
Injector injector = Guice.createInjector(config);
TestImpl test = injector.getInstance(TestImpl.class);
}
}
package com.test;
import com.google.inject.Inject;
import com.google.inject.name.Named;
public class TestImpl {
private final String property1;
private final Integer property2;
@Inject
public TestImpl(@Named("Property1") String property1, @Named("Property2") Integer property2) {
System.out.println("Hello World");
this.property1 = property1;
this.property2 = property2;
System.out.println(property1);
System.out.println(property2);
}
}
今私の質問。 TestImplがプロパティを挿入する必要がある他のクラスを作成し、それらのクラスもプロパティを挿入する必要がある場合、これを行う正しい方法は何ですか?
インジェクターをすべてのサブクラスに渡し、injector.getInstance(...)を使用してサブクラスを作成しますか?
次のような新しいインジェクターをインスタンス化します
TestConfiguration config = new TestConfiguration();
Injector injector = Guice.createInjector(config);
TestImpl test = injector.getInstance(TestImpl.class);
すべてのネストされたクラスで?
インジェクターをすべてのサブクラスに渡し、injector.getInstance(...)を使用してサブクラスを作成しますか?
いいえ、これを行うことで、 依存性注入 パターンの目的を無効にし、すべての実装をGuiceに結合します。 (現在標準化されている)アノテーションを使用する場合を除いて、実装はguiceとまったく対話しないでください。
次のような新しいインジェクターをインスタンス化します
TestConfiguration config = new TestConfiguration(); Injector injector = Guice.createInjector(config); TestImpl test = injector.getInstance(TestImpl.class);
すべてのネストされたクラスで?
いいえ、これはさらに悪いことです。複数のインジェクターが発生するため、複数のコンテキストが原因で、 scopes の適切な使用が妨げられます。
理想的には、アプリケーションのブートストラップ中にのみインジェクターを使用する必要があります。もちろん、bootstrapへの道は、アプリケーションに大きく依存します。
プロパティをすべてのクラスで使用できるようにする他のアプローチはありますか?
プロパティは、TestImplの場合と同じ方法で注入できます。 TestImplを使用したい場合、たとえば、いくつかのプロパティ(または他のサービス)も必要とするサービスを使用する場合は、GuiceにTestImplに注入させます。 Guiceがすべてのインスタンス化/配線を処理しています。 Guiceがそれ自体を理解できない場合にのみ、バインダーを使用してGuiceに「続行する方法」を指示する必要があります。
public class TestImpl {
private final String property1;
private final Integer property2;
private final IService service;
@Inject
public TestImpl(@Named("Property1") String property1, @Named("Property2") Integer property2, IService service) {
this.property1 = property1;
this.property2 = property2;
this.service= service;
}
}
}
ライブラリ「Governator」は、guiceインジェクションの構成マッピング機能を提供します。アプローチは異なりますが、プロパティファイルからのロードが利用可能です。
https://github.com/Netflix/governator/wiki/Configuration-Mapping
ライブラリ Guice設定 プロパティまたはJSONファイルからサービスに値を挿入できます。
ファイルapplication.propertiesからサービスに次のように挿入できます:
@BindConfig(value = "application", syntax = PROPERTIES)
public class Service {
@InjectConfig
private int port;
@InjectConfig
private String url;
@InjectConfig
private Optional<Integer> timeout;
}
モジュールをインストールするだけですConfigurationModule
public class GuiceModule extends AbstractModule {
@Override
protected void configure() {
install(ConfigurationModule.create());
requestInjection(Service.class);
}
}
使用例:最初に、プロパティファイル 'config.properties'があります。
test.key=test value
そして、この値を次のように挿入します。
@Inject
@Config( Property.TEST_KEY )
private String injectedValue;
ファイル 'config.properties'の内容をJava.util.Propertiesにロードし、それをConfigモジュールに渡す必要があります。
Properties props = new Properties();
props.load(...);
モジュールconfigModule = new ConfigModule(props、Property.values()); ...そして注入:
Injector injector = Guice.createInjector( configModule );
TestClass testClass = injector.getInstance( TestClass.class );
String injectedValue = testClass.getInjectedValue();
注入された値は「テスト値」になります。
「質問です。TestImplがプロパティを挿入する必要がある他のクラスを作成し、それらのクラスもプロパティを挿入する必要がある場合、これを行う正しい方法は何ですか?」
経験則:「新しい」の使用は避けてください。どうしても必要な場合を除いて、Implクラスに「他のクラスを作成」させないでください。代わりに、guiceで作成した場合、必要なインスタンスを注入する必要があることをTestImplに伝えます。