web-dev-qa-db-ja.com

GoogleGuiceを使用してJavaプロパティを注入する

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がプロパティを挿入する必要がある他のクラスを作成し、それらのクラスもプロパティを挿入する必要がある場合、これを行う正しい方法は何ですか?

  1. インジェクターをすべてのサブクラスに渡し、injector.getInstance(...)を使用してサブクラスを作成しますか?

  2. 次のような新しいインジェクターをインスタンス化します

    TestConfiguration config = new TestConfiguration();
    Injector injector = Guice.createInjector(config);
    TestImpl test = injector.getInstance(TestImpl.class);
    

すべてのネストされたクラスで?

  1. プロパティをすべてのクラスで使用できるようにする他のアプローチはありますか?
16
markus

インジェクターをすべてのサブクラスに渡し、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;
        }
    }
}
14
Pierre-Henri

ライブラリ「Governator」は、guiceインジェクションの構成マッピング機能を提供します。アプローチは異なりますが、プロパティファイルからのロードが利用可能です。

https://github.com/Netflix/governator/wiki/Configuration-Mapping

3
EIIPII

ライブラリ 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);
    }
}
1
Yves Galante

guice-config


使用例:最初に、プロパティファイル '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();

注入された値は「テスト値」になります。

1

「質問です。TestImplがプロパティを挿入する必要がある他のクラスを作成し、それらのクラスもプロパティを挿入する必要がある場合、これを行う正しい方法は何ですか?」

経験則:「新しい」の使用は避けてください。どうしても必要な場合を除いて、Implクラスに「他のクラスを作成」させないでください。代わりに、guiceで作成した場合、必要なインスタンスを注入する必要があることをTestImplに伝えます。

0
Jan Galinski