2016-07-26 19 views
1

私の全体的な目標は、プロパティファイルからプロパティをロードし、それらのプロパティを自分のオブジェクトに挿入することです。 Guiceを使って特定のシングルトンクラスをインスタンス化するためにこれらのプロパティを使用したいと思います。私のシングルトンクラスは、次のようになります。ランタイムパラメータで設定されたGuiceからシングルトンを取得するにはどうすればよいですか?

public class MainStore(){ 
    private String hostname; 

    @Inject 
    public void setHostname(@Named("hostname") String hostname){ 
    this.hostname = hostname; 
    } 

    public MainStore(){ 
    System.out.println(hostname); 
    } 
} 

私はこのプロバイダを使用してシングルトンのインスタンスを作成しようとしている:

public class MainStoreProvider implements Provider<MainStore> { 
    @Override 
    public MainStore get(){ 
    MainStore mainStore = new MainStore(); 
    return mainStore; 
    } 
} 

マイconfigurationModuleは、実行時に指定されたプロパティファイルから設定をロードするモジュールです。

public class ConfigurationModule extends AbstractModule { 
    @Override 
    protected void configure(){ 
    Properties properties = loadProperties(); 
    Names.bindProperties(binder(), properties); 
    } 

    private static Properties loadProperties() { 
    String resourceFileName = "example.properties"; 
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
    InputStream inputStream = classLoader.getResourceAsStream(resourceFileName); 

    Properties properties = new Properties(); 
    properties.load(inputStream); 

    return properties; 
    } 
} 

そして、私のexample.propertiesファイルが含まれています

私はメインシングルトンを必要とするときそして、私が使用している

Injector injector = Guice.createInjector(new ConfigurationModule()); 
MainStoreProvider mainStoreProvider = injector.getInstance(MainStoreProvider.class); 
MainStore mainStore = mainStoreProvider.get(); //MainClass singleton 

はこれがダウンする正しい道ですか?私はこれをまったく別のやり方で行うべきですか? MainStoreが正しいホスト名を表示しないのはなぜですか?

+0

のシングルトンを作成します。なぜ最初にプロバイダーが必要ですか? guiceはあなたのクラス構築を処理していないので、プロパティを設定しません。プロバイダ実装にプロパティを注入し、作成後にプロパティを設定する必要があります。また、私が間違っている場合は私を修正しますが、あなたのプロバイダはシングルトンを作成せず、毎回新しいインスタンスを作成します。 – pandaadb

+0

私はシングルトンを提供するためにプロバイダを使用したいと思います。私はそれをする方法がわからないので、おそらくそれは間違っている。また、Guiceは、Injectedプロパティをプロバイダで作成されたすべてのクラスにカスケードすると考えました。このアプローチは完全に間違っているかもしれません。 – Grammin

+0

いいえ、guiceではなく、オブジェクトを作成する人であるため、guiceはあなたのために行いません。あなたのホスト名が間違って印刷される理由は、コンストラクタでそれを表示するが、メソッドを注入するからです。メソッドの注入は、オブジェクトが構築された後にのみ起こります(それ以外の方法はありません)。シングルトンが必要な場合は、シングルトンスコープでバインドして、単純にプロパティをコンストラクタに挿入します(メソッドを実行するのと同じです)。あなたのプロパティは、Guice Managedクラスにインジェクトでき​​る名前付き文字列オブジェクトと考えてください。 – pandaadb

答えて

2

私はシングルトンをバインドする方法、プロパティを挿入する方法などを示す小さな例を書いています。

public class TestModule extends AbstractModule { 

    @Override 
    protected void configure() { 
     Properties p = new Properties(); 
     p.setProperty("my.test.string", "Some String"); // works with boolean, int, double .... 
     Names.bindProperties(binder(),p); 
     bind(X.class).to(Test.class).in(Singleton.class); // This is now a guice managed singleton 
    } 

    public interface X { 

    } 

    public static class Test implements X { 

     private String test; 

     @Inject 
     public Test(@Named("my.test.string") String test) { 
      this.test = test; 
      System.out.println(this.test); 
     } 

     public String getTest() { 
      return test; 
     } 
    } 

    public static void main(String[] args) { 

     Injector createInjector = Guice.createInjector(new TestModule()); 
     Test instance = createInjector.getInstance(Test.class); 

    } 
} 

configureメソッドは、guiceに私のTestクラスがシングルトンであることを伝えるようになりました。

コンストラクタを挿入してプロパティを設定するため、正しいホスト名(プロパティテスト)が出力されます。

これはプロバイダでも実行できますが、手動でオブジェクトを作成する必要があります。私の場合、これは次のようになります。

public static class TestProvider implements Provider<X> { 

     private String test; 

     private X instance; 

     public TestProvider(@Named("my.test.string") String test) { 
      this.test = test; 
     } 

     @Override 
     public X get() { 
      if(instance == null) { 
       instance = new Test(test); 
      } 
      return instance; 
     } 

    } 

は、このようになりますバインディング:

bind(X.class).toProvider(TestProvider.class); 

が、これはあなたが望んでますか?

乾杯、

アルトゥル

編集:

bind(X.class).toProvider(TestProvider.class).in(Singleton.class); 

あなたはシングルトンとして、プロバイダをバインドすることができます:私はいくつかのテストを行なったし、注意することはこれを見つけた

あなたはシングルトンの作成を自分で処理する必要はありません。

public static class TestProvider implements Provider<X> { 

     private String test; 

     private X instance; 

     @Inject 
     public TestProvider(@Named("my.test.string") String test) { 
      this.test = test; 
     } 

     @Override 
     public X get() { 
      return instance; 
     } 

    } 

上記のコードは、あなたのプロバイダは、ホスト名のプロパティを設定していないオブジェクトX.

+0

これは間違いなく助けになります!ありがとう! TestModuleからSingleton.classを削除し、それをTestProviderに入れる方法はありますか?私は、プロパティファイルからInjectPropertiesのどこにでもTestModuleを使用したいと思います。 – Grammin

+0

私は分かりません。プロバイダをシングルトンとしてバインドすると、最初に作成された同じインスタンスが返されます。詳細については、私のアップデートを参照してください。さまざまなプロバイダによって、あなたはどういう意味ですか?同じモジュールで複数のインジェクタを作成していますか? – pandaadb

+0

これは私の考える質問に答える。ご助力ありがとうございます。最後に、私がTestProviderをTestModuleに結合する必要がなければ素晴らしいだろう。 – Grammin

関連する問題