2017-11-29 17 views
0

私のプロジェクトではGuiceをDIに使用していますが、私のクラスでは非シングルトンオブジェクトの初期化を怠惰にしたいと思っています。 Providerを使用しようとしていましたが、get()メソッドを呼び出すたびに新しいインスタンスが返されました。guiceの非シングルトンの遅延ロード

public class MyClass { 
    @Inject 
    private Provider<Service> serviceProvider; //Service is NOT Singleton 

    public void meth1() { 
    Service s1 = serviceProvider.get();  
    } 

    public void meth2() { 
    Service s2 = serviceProvider.get(); 
    } 
    //I want s1 and s2 to be the same object 
} 

んGuiceには、それを行うことができ、またはそれを達するために、他のプラクティスはありますか?

+0

「sとs2が同じオブジェクトになりたい」 - なぜですか?それらが同じインスタンスへの2つの参照である場合、なぜ最初に2つの参照が必要ですか? – Thomas

+0

どうしたらいいですか? 'Service s2 = s;'? 「レイジーインジェクション」とはどういう意味ですか? – alfasin

+0

私はメッセージを編集します。今度はもっと明白なことを望みます。 – Andrew

答えて

1

としてコメントに記載されているTavianは、最も良い解決策はSuppliers.memoize(serviceProvider::get)、または同等のものです。 Suppliers(およびSupplier)はGoogleユーティリティライブラリGuavaにあり、Java 8以降、GuavaのサプライヤはJava 8機能インタフェースSupplierを拡張しますが、Java 8はサプライヤと同等のビルトインを提供していません。 serviceProvider::getの仕様は、明示的なアダプタなしでサプライヤとして動作するようにするために必要です。どちらも、1つのメソッド、0引数のT get()を指定しています。

Googleの他のDIフレームワークであるDaggerとは異なり、サプライヤはあなたが探しているローカルメモを提供するためにLazyクラスを持っていません。 tmarwenがtheir updated answerで提供しているような種類の「チェックして設定する」動作を行うことはできますが、その戦略は(スレッドのコメントに記載されているように)スレッドセーフではなく、Suppliers.memoizeはスレッドセーフです。

Guavaは多くの便利な機能を備えていますが、1つのメソッドに完全な新しいライブラリを追加したくない場合があります。ライブラリ全体がなくてもスレッドセーフティが必要な場合は、the Apache-licensed implementation hereをご覧ください。

+1

Guiceはこの機能をボックスからは提供しませんが、GuavaのSuppliersを使用するのは簡単です。ありがとう! – Andrew

1

あなたが同じインスタンスを参照するためにs1s2が必要な場合は、あなただけのMyClassとどのインスタンスフィールドに簡単に解決するのインスタンスのServiceの単一のインスタンスが必要になります。

public class MyClass { 

    @Inject 
    private Provider<Service> serviceProvider; 

    private Service service; 

    public void meth1() { 
    if (this.service == null) this.service = this.serviceProvider.get(); 
    // use service 
    } 

    public void meth2() { 
    if (this.service == null) this.service = this.serviceProvider.get(); 
    // use service 
    } 
} 
+0

サービスの遅延初期化ではありません。私は、サービスがmeth1またはmeth2でのみ初期化されることを望んでいます。 – Andrew

+0

あなたの要件に合わせて答えを更新しましたが、このアプローチは最適なものではなく、特にスレッドセーフではありません。 – tmarwen