軽量GoogleのGuiceの依存性注入フレームワーク

Githubの主页:https://github.com/google/guice
API:http://google.github.io/guice/api-docs/4.0/javadoc/

Guiceの(「ジュース」を発音)GoogleがあなたにもたらしたJava 6以上のための軽量の依存性注入フレームワークです。軽量の依存性注入フレームワーク。

Springの依存性注入について、参照  春の依存性注入DIの道を

GoogleのGuiceの例を参照してください  GoogleのGuiceのにガイド
たとえば、我々は  Communication実際に使用するクラス  Communicator実際にメッセージを送信します。

Mavenの依存関係を追加します。

<dependency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>4.0</version>
</dependency>

私たちは、最初に定義する  Communicatorインターフェースを、そのクラスの実現  DefaultCommunicatorImpl

public interface Communicator {
    boolean sendMessage(String message);
}
public class DefaultCommunicatorImpl implements Communicator {
    public boolean sendMessage(String message) {
        System.out.println("Sending Message + " + message);
        return true;
    }
}

その後、我々は渡さ  @Injectにメモを  Communication注入し、クラス  Communicator依存クラス:

import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;

import java.util.logging.Logger;

public class Communication {
    @Inject
    private Communicator communicator;

    public Communication(Boolean keepRecords) {
        if (keepRecords) {
            System.out.println("Message logging enabled");
        }
    }

    public boolean sendMessage(String message) {
        communicator.sendMessage(message);
        return true;
    }

    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new BasicModule());

        Communication comms = injector.getInstance(Communication.class);

        comms.sendMessage("hello world");
    }
}

では  main()、あなたは私たちを見抜くことができます  Injector取得するには  Communication、その後、インスタンスを呼び出す  sendMessage()方法を。

その後、  BasicModuleクラスがどのようにそれのようなものでしょうか?

モジュールは、定義の基本単位である バインディング。 ベースユニットが結合依存定義しました。

  • これは、継承する必要がある  AbstractModuleクラス
  • これは、  Communicationインスタンスのインスタンスにバインドされ、引数が渡された  trueコンストラクタに
  • それはされる  Communicator特定の実装にバインド DefaultCommunicatorImpl
import com.google.inject.AbstractModule;

public class BasicModule extends AbstractModule {

    @Override
    protected void configure() {
        // 表明:当需要 Communicator 这个变量时,我们注入 DefaultCommunicatorImpl 的实例作为依赖
        bind(Communicator.class).to(DefaultCommunicatorImpl.class);

        bind(Communication.class)
                .toInstance(new Communication(true));
    }
}

次の出力を実行します。

メッセージロギングは有効に
メッセージ+ハロー世界を送信します

私たちは、注入コード形式にし、管理はむしろXML設定ファイルを通じてよりも、依存していて、Guiceのを見ることができ、そしてこの春は同じではありません。

また、することができます  @Providesでの注釈  BasicModuleに定義依存:

public class BasicModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(Communication.class)
                .toInstance(new Communication(true));
    }

    @Provides
    @Singleton
    public Communicator getCommunicator() {
        return new DefaultCommunicatorImpl();
    }
}

前記  @Singleton注釈は、これは単一依存スコープ実施形態であることを示し、それはレイジー開始ロード遅延です。

我々は、複数のバインディングに依存していた場合は、例えば:

@Provides
@Singleton
public Communicator getCommunicator() {
    return new DefaultCommunicatorImpl();
}

@Provides
@Singleton
public Communicator getCommunicatorOneMoreTime() {
    return new DefaultCommunicatorImpl();
}

これは、次の例外ランタイムがスローされます。

1) A binding to demo.guice.Communicator was already configured at demo.guice.BasicModule.getCommunicator().
  at demo.guice.BasicModule.getCommunicator(BasicModule.java:17)

1 error
    at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466)
    at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
    at com.google.inject.Guice.createInjector(Guice.java:96)
    at com.google.inject.Guice.createInjector(Guice.java:73)
    at com.google.inject.Guice.createInjector(Guice.java:62)

我々は今持っている場合は  Communicator、別の実現のインターフェースを  AnotherCommunicatorImpl

public class AnotherCommunicatorImpl implements Communicator {
    public boolean sendMessage(String message) {
        System.out.println("Another Sending Message + " + message);
        return true;
    }
}

で私たち  Communicationの古いに依存するクラスの必要性  DefaultCommunicatorImplと新しい定義  AnotherCommunicatorImplなど、:

public class Communication {

    @Inject
    private Communicator communicator;

    @Inject
    private Communicator anotherCommunicator;

    public Communication(Boolean keepRecords) {
        if (keepRecords) {
            System.out.println("Message logging enabled");
        }
    }

    public boolean sendMessage(String message) {
        communicator.sendMessage(message);

        anotherCommunicator.sendMessage(message);

        return true;
    }

    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new BasicModule());

        Communication comms = injector.getInstance(Communication.class);

        comms.sendMessage("hello world");
    }
}

だから我々は  BasicModuleこのことをバインドする方法を定義する必要がありますか?
私たちは別の追加しようとする  @Provides方法をそのリターン  AnotherCommunicatorImpl例えば、:

@Provides
@Singleton
public Communicator getCommunicator() {
    return new DefaultCommunicatorImpl();
}

@Provides
@Singleton
public Communicator getAnotherCommunicator() {
    return new AnotherCommunicatorImpl();
}

それは、次の例外があります:

Exception in thread "main" com.google.inject.CreationException: Unable to create injector, see the following errors:

1) A binding to demo.guice.Communicator was already configured at demo.guice.BasicModule.getCommunicator().
  at demo.guice.BasicModule.getAnotherCommunicator(BasicModule.java:23)

ここでは、する必要があり  @Named、関数の注釈のプロパティの割り当てを提供します。
結合注入するときに最初に使用する  @Named注釈を:

@Inject
@Named("communicator")
private Communicator communicator;

@Inject
@Named("anotherCommunicator")
private Communicator anotherCommunicator;

バインディング定義するときに次に使う  @Namedノートを:

@Provides
@Singleton
@Named("communicator")
public Communicator getCommunicator() {
    return new DefaultCommunicatorImpl();
}

@Provides
@Singleton
@Named("anotherCommunicator")
public Communicator getAnotherCommunicator() {
    return new AnotherCommunicatorImpl();
}

結果は以下の通りであります:

メッセージロギングが有効になっ
メッセージ+ハロー世界を送信する
別の送信メッセージ+ハロー世界を

Guiceの作品

全体:

  • Guice:フレームワークのファサード
  • Injector:文脈依存の管理
  • Binder:インターフェイスと結合の実装
  • Module:のグループ Binder
  • Provider:Beanプロバイダ
  • KeyBinderAに対応 Provider
  • ScopeProvider対象範囲

各バインディングは  Binding<T>、以下の構造を有します:

public interface Binding<T> extends Element {
    Key<T> getKey();

    Provider<T> getProvider();

それが継承すると同時に、  Elementソースが含まれています:

public interface Element {
    Object getSource();

それぞれ見ることができる結合  Binding<T>キー備え、  Key<T>およびプロバイダを  Provider

  • キーは  Key<T>一意に各結合を決定します。 キーは  Key<T>顧客コードは、タイプ、およびオプションのラベルに依存含まれています。あなたは、同じタイプの複数の結合点の間を区別するために注釈を使用することができます。

    • 例えば、上記のコードでは、Communicatorタイプは、2つのキーを有します。
    • Key[type=demo.guice.Communicator, [email protected](value=communicator)]
    • Key[type=demo.guice.Communicator, [email protected](value=anotherCommunicator)]
  • 各プロバイダの  Providerタイプの所望のインスタンスを提供します。

    • あなたがクラスを提供することができ、Guiceのは、あなたがそれのインスタンスを作成するのに役立ちます。
    • また、あなたがクラスをバインドするのGuiceの例を与えることができます。
    • また、あなた自身を実装することができます  Provider<T>Guiceのがそれに依存性を注入することができ、。
    • 例えば、上記のコードは、プロバイダがあります class demo.guice.DefaultCommunicatorImpl
  • 各結合およびオプションのスコープ。ノースコープデフォルトBIND、Guiceのは、新しいオブジェクトを作成するたびに注入します。カスタムスコープは、新しいオブジェクトを作成するかどうかをGuiceのを制御することができます。たとえば、HttpSessionのそれぞれのインスタンスを作成するために使用することができます。

私たちは、それぞれの方法による結合を介しすることができます Binding<T>

Injector injector = Guice.createInjector(new BasicModule());

Map<Key<?>, Binding<?>> bindings = injector.getBindings();

for (Map.Entry<Key<?>, Binding<?>> bingingEntry : bindings.entrySet()) {

    Binding binging = bingingEntry.getValue();

    Key key =  binging.getKey();
    Provider provider = binging.getProvider();

    System.out.println("Key: " + key.toString());

    System.out.println("Provider: " + provider.get().getClass());

    System.out.println("************");
}

次のように出力されます。

Key: Key[type=com.google.inject.Stage, annotation=[none]]
Provider: class com.google.inject.Stage
************
Key: Key[type=com.google.inject.Injector, annotation=[none]]
Provider: class com.google.inject.internal.InjectorImpl
************
Key: Key[type=java.util.logging.Logger, annotation=[none]]
Provider: class java.util.logging.Logger
************
Key: Key[type=demo.guice.Communication, annotation=[none]]
Provider: class demo.guice.Communication
************
Key: Key[type=demo.guice.Communicator, [email protected](value=communicator)]
Provider: class demo.guice.DefaultCommunicatorImpl
************
Key: Key[type=demo.guice.Communicator, [email protected](value=anotherCommunicator)]
Provider: class demo.guice.AnotherCommunicatorImpl
************

injector.getInstance(XXX.class);プロセス:
最初に指定されたクラス  new Key()Keyクラス情報を含む  XXX.classと注釈情報XXX.classへ  hashcodeと注釈  hashcode決定  Keyの  hashcodegetProvider記載  Keyに  hashcode同じかどうかを決定するためにKey、その後に採取  Providerすることにより  Provider、最終的なサンプルを提供します。
上記の例  Key[type=demo.guice.Communicator, [email protected](value=communicator)]と  、それぞれに  及び  Key[type=demo.guice.Communicator, [email protected](value=anotherCommunicator)]hashcode-1491509781349671560

GuiceのDIと春のDIを比較

参照してください  春とGuiceの違い

  • 使用します。

    • 春はXMLに、クラスとクラス分離の関係になり、コンテナが呼び出されているオブジェクトを注入するための責任があります
    • Guiceのは、XMLが、アノテーションアノテーションの使用を使用していません
  • 業務の効率化:

    • GuiceのGuiceのがない一方で、注釈の注釈、CGLIB、高効率、そしてこの春、最も明白な違いであるを使用して、春を注入するために使用される場合、それは、フィニッシュに注入されている場所の注入にコンフィギュレーションファイルをロードするための時間です高い動作効率と柔軟性。
  • タイプのカップリング:

    • 春のカップリングローを外部依存の方法で、非侵襲的に基づく強調、クラスの内部には、設定ファイルの大騒ぎで、とてもきれいです
    • 高結合、示さコードレベル、DIフラグGuiceの  @injectクラスレベルアップに結合された侵入コードを、



著者:フルタイムウォーク・オン
リンクします。https://www.jianshu.com/p/7fba7b43146a
出典:ジェーン・ブック
著者によって予約ジェーンブックの著作権は、いかなる形で再現され、承認を得るために、作者に連絡して、ソースを明記してください。

リリース6元記事 ウォン称賛43 ビュー570 000 +

おすすめ

転載: blog.csdn.net/hany3000/article/details/100159754