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プロバイダKey
:Binder
Aに対応Provider
Scope
:Provider
対象範囲
各バインディングは 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
の hashcode
、getProvider
記載 Key
に hashcode
同じかどうかを決定するためにKey
、その後に採取 Provider
することにより Provider
、最終的なサンプルを提供します。
上記の例 Key[type=demo.guice.Communicator, [email protected](value=communicator)]
と 、それぞれに 及び 。Key[type=demo.guice.Communicator, [email protected](value=anotherCommunicator)]
hashcode
-1491509781
349671560
GuiceのDIと春のDIを比較
参照してください 春とGuiceの違い
-
使用します。
- 春はXMLに、クラスとクラス分離の関係になり、コンテナが呼び出されているオブジェクトを注入するための責任があります
- Guiceのは、XMLが、アノテーションアノテーションの使用を使用していません
-
業務の効率化:
- GuiceのGuiceのがない一方で、注釈の注釈、CGLIB、高効率、そしてこの春、最も明白な違いであるを使用して、春を注入するために使用される場合、それは、フィニッシュに注入されている場所の注入にコンフィギュレーションファイルをロードするための時間です高い動作効率と柔軟性。
-
タイプのカップリング:
- 春のカップリングローを外部依存の方法で、非侵襲的に基づく強調、クラスの内部には、設定ファイルの大騒ぎで、とてもきれいです
- 高結合、示さコードレベル、DIフラグGuiceの
@inject
クラスレベルアップに結合された侵入コードを、
著者:フルタイムウォーク・オン
リンクします。https://www.jianshu.com/p/7fba7b43146a
出典:ジェーン・ブック
著者によって予約ジェーンブックの著作権は、いかなる形で再現され、承認を得るために、作者に連絡して、ソースを明記してください。