GoogleGuice-クイックガイド
Guiceは、オープンソースのJavaベースの依存性注入フレームワークです。静かで軽量で、Googleによって積極的に開発/管理されています。
依存性注入
すべてのJavaベースのアプリケーションには、エンドユーザーが機能しているアプリケーションと見なすものを提示するために連携して機能するいくつかのオブジェクトがあります。複雑なJavaアプリケーションを作成する場合、アプリケーションクラスは他のJavaクラスから可能な限り独立している必要があります。これにより、これらのクラスを再利用し、単体テスト中に他のクラスから独立してテストできるようになります。依存性注入(またはワイヤリングと呼ばれることもあります)は、これらのクラスを結合すると同時に、それらを独立させるのに役立ちます。
テキストエディタコンポーネントを備えたアプリケーションがあり、スペルチェックを提供したいとします。標準コードは次のようになります-
public class TextEditor {
private SpellChecker spellChecker;
public TextEditor() {
spellChecker = new SpellChecker();
}
}
ここで行ったことは、TextEditorとSpellCheckerの間に依存関係を作成することです。制御の反転シナリオでは、代わりに次のようなことを行います-
public class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
}
ここで、TextEditorはSpellCheckerの実装について心配する必要はありません。SpellCheckerは独立して実装され、TextEditorのインスタンス化時にTextEditorに提供されます。
Guiceを使用した依存性注入(バインディング)
依存性注入は、GuiceBindingsによって制御されます。Guiceはバインディングを使用して、オブジェクトタイプを実際の実装にマップします。これらのバインディングはモジュールとして定義されています。モジュールは、以下に示すようにバインディングのコレクションです。
public class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
/*
* Bind SpellChecker binding to WinWordSpellChecker implementation
* whenever spellChecker dependency is used.
*/
bind(SpellChecker.class).to(WinWordSpellChecker.class);
}
}
モジュールは、Guiceのオブジェクトグラフビルダーであるインジェクターのコアビルディングブロックです。最初のsteoはインジェクターを作成することであり、次にインジェクターを使用してオブジェクトを取得できます。
public static void main(String[] args) {
/*
* Guice.createInjector() takes Modules, and returns a new Injector
* instance. This method is to be called once during application startup.
*/
Injector injector = Guice.createInjector(new TextEditorModule());
/*
* Build object using injector
*/
TextEditor textEditor = injector.getInstance(TextEditor.class);
}
上記の例では、TextEditorクラスオブジェクトグラフはGuiceによって作成され、このグラフにはTextEditorオブジェクトとその依存関係がWinWordSpellCheckerオブジェクトとして含まれています。
ローカル環境のセットアップ
それでもJavaプログラミング言語用の環境をセットアップする場合は、このセクションで、マシンにJavaをダウンロードしてセットアップする方法について説明します。以下の手順で環境を設定してください。
Java SEは、Javaのダウンロードリンクから無料で入手できます。したがって、オペレーティングシステムに基づいたバージョンをダウンロードします。
指示に従ってJavaをダウンロードし、 .exeマシンにJavaをインストールします。マシンにJavaをインストールしたら、正しいインストールディレクトリを指すように環境変数を設定する必要があります-
Windows 2000 / XPのパスの設定
Javaがc:\ Program Files \ java \ jdkディレクトリにインストールされていることを前提としています-
「マイコンピュータ」を右クリックし、「プロパティ」を選択します。
[詳細設定]タブの下にある[環境変数]ボタンをクリックします。
ここで、「Path」変数を変更して、Java実行可能ファイルへのパスも含まれるようにします。たとえば、パスが現在「C:\ WINDOWS \ SYSTEM32」に設定されている場合は、パスを「C:\ WINDOWS \ SYSTEM32; c:\ ProgramFiles \ java \ jdk \ bin」に変更します。
Windows 95/98 / MEのパスの設定
Javaがc:\ Program Files \ java \ jdkディレクトリにインストールされていることを前提としています-
'C:\ autoexec.bat'ファイルを編集し、最後に次の行を追加します-'SET PATH =%PATH%; C:\ Program Files \ java \ jdk \ bin '
Linux、UNIX、Solaris、FreeBSDのパスの設定
環境変数PATHは、Javaバイナリがインストールされている場所を指すように設定する必要があります。これを行うのに問題がある場合は、シェルのドキュメントを参照してください。
たとえば、シェルとしてbashを使用する場合は、「。bashrc:export PATH = / path / to / java:$ PATH」の末尾に次の行を追加します。
人気のあるJavaエディター
Javaプログラムを作成するには、テキストエディタが必要です。市場には多くの洗練されたIDEがあります。しかし今のところ、あなたは次のいずれかを考えることができます-
Notepad − Windowsマシンでは、メモ帳(このチュートリアルに推奨)、TextPadなどの単純なテキストエディターを使用できます。
Netbeans −オープンソースで無料のJava IDEであり、からダウンロードできます。 https://www.netbeans.org/index.html。
Eclipse −これはEclipseオープンソースコミュニティによって開発されたJava IDEでもあり、からダウンロードできます。 https://www.eclipse.org/。
GoogleGuice環境
GoogleGuiceの最新バージョンと関連するjarファイルをダウンロードします。
Google Guice 4.0
AOPアライアンス1.0
グアバ16.0.1
javax.inject 1.0
このチュートリアルを書いている時点で、それらをC:\> Googleフォルダーにコピーしています。
OS | アーカイブ名 |
---|---|
ウィンドウズ | guice-4.1.0.jar; aopalliance-1.0.jar; guava-16.0.1.jar; javax.inject-1.jar |
Linux | guice-4.1.0.jar; aopalliance-1.0.jar; guava-16.0.1.jar; javax.inject-1.jar |
マック | guice-4.1.0.jar; aopalliance-1.0.jar; guava-16.0.1.jar; javax.inject-1.jar |
CLASSPATH変数を設定する
をセットする CLASSPATHGuicejarの場所を指す環境変数。次のように、さまざまなオペレーティングシステムのGoogleフォルダにGuiceと関連するjarファイルを保存したと仮定します。
OS | 出力 |
---|---|
ウィンドウズ | 環境変数CLASSPATHを%CLASSPATH%; C:\ Google \ guice-4.1.0.jar; C:\ Google \ aopalliance-1.0.jar; C:\ Google \ guava-16.0.1.jar; C:\に設定しますGoogle \ javax.inject-1.jar;。; |
Linux | export CLASSPATH = $ CLASSPATH:Google / guice-4.1.0.jar:Google / aopalliance-1.0.jar:Google / guava-16.0.1.jar:Google /javax.inject-1.jar:。 |
マック | export CLASSPATH = $ CLASSPATH:Google / guice-4.1.0.jar:Google / aopalliance-1.0.jar:Google / guava-16.0.1.jar:Google /javax.inject-1.jar:。 |
サンプルのコンソールベースのアプリケーションを作成して、Guiceバインディングメカニズムを使用した依存性注入を段階的に示します。
ステップ1:インターフェースを作成する
//spell checker interface
interface SpellChecker {
public void checkSpelling();
}
ステップ2:実装を作成する
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
ステップ3:バインディングモジュールを作成する
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(SpellChecker.class).to(SpellCheckerImpl.class);
}
}
ステップ4:依存関係のあるクラスを作成する
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
ステップ5:インジェクターを作成する
Injector injector = Guice.createInjector(new TextEditorModule());
ステップ6:依存関係が満たされたオブジェクトを取得します。
TextEditor editor = injector.getInstance(TextEditor.class);
手順7:オブジェクトを使用します。
editor.makeSpellCheck();
完全な例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(SpellChecker.class).to(SpellCheckerImpl.class);
}
}
//spell checker interface
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside checkSpelling.
リンクされたバインディングでは、Guiceはタイプをその実装にマップします。以下の例では、SpellCheckerインターフェースをその実装SpellCheckerImplにマップしました。
bind(SpellChecker.class).to(SpellCheckerImpl.class);
具象クラスをそのサブクラスにマッピングすることもできます。以下の例を参照してください。
bind(SpellCheckerImpl.class).to(WinWordSpellCheckerImpl.class);
ここでは、バインディングをチェーンしました。完全な例で結果を見てみましょう。
完全な例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(SpellChecker.class).to(SpellCheckerImpl.class);
bind(SpellCheckerImpl.class).to(WinWordSpellCheckerImpl.class);
}
}
//spell checker interface
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
//subclass of SpellCheckerImpl
class WinWordSpellCheckerImpl extends SpellCheckerImpl{
@Override
public void checkSpelling() {
System.out.println("Inside WinWordSpellCheckerImpl.checkSpelling." );
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside WinWordSpellCheckerImpl.checkSpelling.
型をその実装にバインドできるため。複数の実装を持つタイプをマップする場合は、カスタムアノテーションを作成することもできます。概念を理解するには、以下の例を参照してください。
バインディングアノテーションを作成する
@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
@interface WinWord {}
@BindingAnnotation -アノテーションをバインディングアノテーションとしてマークします。
@Target -注釈の適用可能性をマークします。
@Retention -アノテーションの可用性をランタイムとしてマークします。
バインディングアノテーションを使用したマッピング
bind(SpellChecker.class).annotatedWith(WinWord.class).to(WinWordSpellCheckerImpl.class);
バインディングアノテーションを使用して挿入
@Inject
public TextEditor(@WinWord SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
完全な例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import java.lang.annotation.Target;
import com.google.inject.AbstractModule;
import com.google.inject.BindingAnnotation;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
@interface WinWord {}
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor(@WinWord SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(SpellChecker.class).annotatedWith(WinWord.class)
.to(WinWordSpellCheckerImpl.class);
}
}
//spell checker interface
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
//subclass of SpellCheckerImpl
class WinWordSpellCheckerImpl extends SpellCheckerImpl{
@Override
public void checkSpelling() {
System.out.println("Inside WinWordSpellCheckerImpl.checkSpelling." );
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside WinWordSpellCheckerImpl.checkSpelling.
Guiceは、カスタムの注釈を作成せずにバインディングをマップする別の方法も提供します。@Namedアノテーションを使用してそうすることができます。
名前付き注釈を使用したマッピング
bind(SpellChecker.class).annotatedWith(Names.named("OpenOffice")).to(OpenOfficeWordSpellCheckerImpl.class);
@Namedアノテーションを使用して挿入
@Inject
public TextEditor(@Named("OpenOffice") SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
完全な例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor(@Named("OpenOffice") SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(SpellChecker.class).annotatedWith(Names.named("OpenOffice"))
.to(OpenOfficeWordSpellCheckerImpl.class);
}
}
//spell checker interface
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
//subclass of SpellCheckerImpl
class OpenOfficeWordSpellCheckerImpl extends SpellCheckerImpl{
@Override
public void checkSpelling() {
System.out.println("Inside OpenOfficeWordSpellCheckerImpl.checkSpelling." );
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside OpenOfficeWordSpellCheckerImpl.checkSpelling.
Guiceは、値オブジェクトまたは定数を使用してバインディングを作成する方法を提供します。JDBCURLを構成する場合を考えてみます。
@Namedアノテーションを使用して挿入
@Inject
public void connectDatabase(@Named("JBDC") String dbUrl) {
//...
}
これは、toInstance()メソッドを使用して実現できます。
bind(String.class).annotatedWith(Names.named("JBDC")).toInstance("jdbc:mysql://localhost:5326/emp");
完全な例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeConnection();
}
}
class TextEditor {
private String dbUrl;
@Inject
public TextEditor(@Named("JDBC") String dbUrl) {
this.dbUrl = dbUrl;
}
public void makeConnection(){
System.out.println(dbUrl);
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(String.class)
.annotatedWith(Names.named("JDBC"))
.toInstance("jdbc:mysql://localhost:5326/emp");
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
jdbc:mysql://localhost:5326/emp
Guiceは、@ providesメソッドを使用して複雑なオブジェクトとのバインディングを作成する方法を提供します。
@Provides
public SpellChecker provideSpellChecker(){
String dbUrl = "jdbc:mysql://localhost:5326/emp";
String user = "user";
int timeout = 100;
SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
return SpellChecker;
}
この方法はBindingModuleの一部であり、マッピングされる複雑なオブジェクトを提供します。以下の完全な例を参照してください。
完全な例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provides;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor( SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {}
@Provides
public SpellChecker provideSpellChecker(){
String dbUrl = "jdbc:mysql://localhost:5326/emp";
String user = "user";
int timeout = 100;
SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
return SpellChecker;
}
}
//spell checker interface
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
private String dbUrl;
private String user;
private Integer timeout;
@Inject
public SpellCheckerImpl(String dbUrl,
String user,
Integer timeout){
this.dbUrl = dbUrl;
this.user = user;
this.timeout = timeout;
}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
System.out.println(dbUrl);
System.out.println(user);
System.out.println(timeout);
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside checkSpelling.
jdbc:mysql://localhost:5326/emp
user
100
@providesメソッドがより複雑になると、これらのメソッドは、プロバイダーインターフェイスを使用して個別のクラスに移動できます。
class SpellCheckerProvider implements Provider<SpellChecker>{
@Override
public SpellChecker get() {
String dbUrl = "jdbc:mysql://localhost:5326/emp";
String user = "user";
int timeout = 100;
SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
return SpellChecker;
}
}
次のステップは、プロバイダーをタイプにマップすることです。
bind(SpellChecker.class).toProvider(SpellCheckerProvider.class);
以下の完全な例を参照してください。
完全な例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor( SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(SpellChecker.class)
.toProvider(SpellCheckerProvider.class);
}
}
//spell checker interface
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
private String dbUrl;
private String user;
private Integer timeout;
@Inject
public SpellCheckerImpl(String dbUrl,
String user,
Integer timeout){
this.dbUrl = dbUrl;
this.user = user;
this.timeout = timeout;
}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
System.out.println(dbUrl);
System.out.println(user);
System.out.println(timeout);
}
}
class SpellCheckerProvider implements Provider<SpellChecker>{
@Override
public SpellChecker get() {
String dbUrl = "jdbc:mysql://localhost:5326/emp";
String user = "user";
int timeout = 100;
SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
return SpellChecker;
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside checkSpelling.
jdbc:mysql://localhost:5326/emp
user
100
Guiceは、toConstructor()メソッドを使用して、オブジェクトの特定のコンストラクターとのバインディングを作成する方法を提供します。
@Override
protected void configure() {
try {
bind(SpellChecker.class)
.toConstructor(SpellCheckerImpl.class.getConstructor(String.class));
} catch (NoSuchMethodException | SecurityException e) {
System.out.println("Required constructor missing");
}
}
以下の完全な例を参照してください。
完全な例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor( SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
try {
bind(SpellChecker.class)
.toConstructor(SpellCheckerImpl.class.getConstructor(String.class));
} catch (NoSuchMethodException | SecurityException e) {
System.out.println("Required constructor missing");
}
bind(String.class)
.annotatedWith(Names.named("JDBC"))
.toInstance("jdbc:mysql://localhost:5326/emp");
}
}
//spell checker interface
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
private String dbUrl;
public SpellCheckerImpl(){}
public SpellCheckerImpl(@Named("JDBC") String dbUrl){
this.dbUrl = dbUrl;
}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
System.out.println(dbUrl);
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside checkSpelling.
jdbc:mysql://localhost:5326/emp
Guiceは、java.util.logging.Loggerクラスの組み込みバインディングを提供します。ロガーの名前は、ロガーが注入されるクラスの名前に自動的に設定されます。以下の例を参照してください。
例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import java.util.logging.Logger;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private Logger logger;
@Inject
public TextEditor( Logger logger) {
this.logger = logger;
}
public void makeSpellCheck(){
logger.info("In TextEditor.makeSpellCheck() method");
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Dec 20, 2017 12:51:05 PM TextEditor makeSpellCheck
INFO: In TextEditor.makeSpellCheck() method
バインディングはバインディングモジュールで定義されているため、Guiceは依存性を注入する必要があるときはいつでもそれらを使用します。バインディングが存在しない場合、ジャストインタイムバインディングの作成を試みることができます。バインディングモジュールに存在するバインディングは明示的バインディングと呼ばれ、優先順位が高くなりますが、ジャストインタイムバインディングは暗黙的バインディングと呼ばれます。両方のタイプのバインディングが存在する場合、明示的なバインディングがマッピングの対象と見なされます。
以下は、3種類のジャストインタイムバインディングの例です。
製本タイプ | 説明 |
---|---|
注射可能なコンストラクター | 非プライベートで引数のないコンストラクターは、ジャストインタイムバインディングの対象となります。もう1つの方法は、コンストラクターに@Injectアノテーションを付けることです。 |
@ImplementatedByアノテーション | @ImplementatedByアノテーションは、実装クラスについてのガイドに伝えます。このような場合、バインディングモジュールでバインディングは必要ありません。 |
@ProvidedByアノテーション | @ProvidedByアノテーションは、実装クラスのプロバイダーについてのガイドを示します。このような場合、バインディングモジュールでバインディングは必要ありません。 |
非プライベートで引数のないコンストラクターは、ジャストインタイムバインディングの対象となります。もう1つの方法は、コンストラクターに@Injectアノテーションを付けることです。例を参照してください。
例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor( SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(SpellChecker.class).to(SpellCheckerImpl.class);
bind(String.class)
.annotatedWith(Names.named("JDBC"))
.toInstance("jdbc:mysql://localhost:5326/emp");
}
}
//spell checker interface
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
@Inject @Named("JDBC")
private String dbUrl;
public SpellCheckerImpl(){}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
System.out.println(dbUrl);
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside checkSpelling.
jdbc:mysql://localhost:5326/emp
@ImplementatedByアノテーションは、実装クラスについてのガイドに伝えます。このような場合、バインディングモジュールでバインディングは必要ありません。例を参照してください。
例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor( SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(String.class)
.annotatedWith(Names.named("JDBC"))
.toInstance("jdbc:mysql://localhost:5326/emp");
}
}
@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
@Inject @Named("JDBC")
private String dbUrl;
public SpellCheckerImpl(){}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
System.out.println(dbUrl);
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside checkSpelling.
jdbc:mysql://localhost:5326/emp
@ProvidedByアノテーションは、実装クラスのプロバイダーについてのガイドを示します。このような場合、バインディングモジュールでバインディングは必要ありません。例を参照してください。
例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.ProvidedBy;
import com.google.inject.Provider;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor( SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
}
}
@ProvidedBy(SpellCheckerProvider.class)
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
private String dbUrl;
private String user;
private Integer timeout;
@Inject
public SpellCheckerImpl(String dbUrl,
String user,
Integer timeout){
this.dbUrl = dbUrl;
this.user = user;
this.timeout = timeout;
}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
System.out.println(dbUrl);
System.out.println(user);
System.out.println(timeout);
}
}
class SpellCheckerProvider implements Provider<SpellChecker>{
@Override
public SpellChecker get() {
String dbUrl = "jdbc:mysql://localhost:5326/emp";
String user = "user";
int timeout = 100;
SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
return SpellChecker;
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside checkSpelling.
jdbc:mysql://localhost:5326/emp
user
100
インジェクションは、オブジェクトに依存関係を注入するプロセスです。コンストラクター注入は非常に一般的です。このプロセスでは、依存関係がコンストラクターへの引数として挿入されます。以下の例を参照してください。
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(SpellChecker.class).to(SpellCheckerImpl.class);
}
}
//spell checker interface
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside checkSpelling.
インジェクションは、オブジェクトに依存関係を注入するプロセスです。メソッドインジェクションは、値オブジェクトをオブジェクトへの依存関係として設定するために使用されます。以下の例を参照してください。
例
GuiceTesterという名前のJavaクラスを作成します。
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor( SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(String.class)
.annotatedWith(Names.named("JDBC"))
.toInstance("jdbc:mysql://localhost:5326/emp");
}
}
@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
private String dbUrl;
public SpellCheckerImpl(){}
@Inject
public void setDbUrl(@Named("JDBC") String dbUrl){
this.dbUrl = dbUrl;
}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
System.out.println(dbUrl);
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside checkSpelling.
jdbc:mysql://localhost:5326/emp
インジェクションは、オブジェクトに依存関係を注入するプロセスです。フィールドインジェクションは、オブジェクトのフィールドへの依存関係として値オブジェクトを設定するために使用されます。以下の例を参照してください。
例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor( SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(String.class)
.annotatedWith(Names.named("JDBC"))
.toInstance("jdbc:mysql://localhost:5326/emp");
}
}
@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
@Inject @Named("JDBC")
private String dbUrl;
public SpellCheckerImpl(){}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
System.out.println(dbUrl);
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside checkSpelling.
jdbc:mysql://localhost:5326/emp
インジェクションは、オブジェクトに依存関係を注入するプロセスです。オプションの注入とは、依存関係が存在する場合に注入することを意味します。メソッドインジェクションとフィールドインジェクションはオプションで依存する場合があり、依存関係が存在しない場合はデフォルト値が必要です。以下の例を参照してください。
例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor( SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {}
}
@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
private String dbUrl = "jdbc:mysql://localhost:5326/emp";
public SpellCheckerImpl(){}
@Inject(optional=true)
public void setDbUrl(@Named("JDBC") String dbUrl){
this.dbUrl = dbUrl;
}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
System.out.println(dbUrl);
}
}
出力
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside checkSpelling.
jdbc:mysql://localhost:5326/emp
インジェクションは、オブジェクトに依存関係を注入するプロセスです。メソッドおよびフィールドインジェクションは、injector.injectMembers()メソッドを使用して既存のオブジェクトを使用して初期化するために使用できます。以下の例を参照してください。
例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
SpellChecker spellChecker = new SpellCheckerImpl();
injector.injectMembers(spellChecker);
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public void setSpellChecker(SpellChecker spellChecker){
this.spellChecker = spellChecker;
}
public TextEditor() { }
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
}
}
@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
public SpellCheckerImpl(){}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
ファイルをコンパイルして実行すると、次の出力が表示されます。
Inside checkSpelling.
Guiceは、デフォルトの動作として値を提供するたびに、新しいインスタンスを返します。スコープを介して構成できます。Guiceがサポートするスコープは次のとおりです。
@Singleton-アプリケーションの存続期間中の単一インスタンス。@Singletonオブジェクトはスレッドセーフである必要があります。
@SessionScoped-Webアプリケーションの特定のセッションの単一インスタンス。@SessionScopedオブジェクトはスレッドセーフである必要があります。
@RequestScoped-Webアプリケーションの特定の要求に対する単一のインスタンス。@RequestScopedオブジェクトはスレッドセーフである必要はありません。
スコープを適用する方法。
スコープを適用する方法は次のとおりです。
クラスレベルで
@Singleton
class SpellCheckerImpl implements SpellChecker {
public SpellCheckerImpl(){}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
構成レベルで
bind(SpellChecker.class).to(SpellCheckerImpl.class).in(Singleton.class);
メソッドレベルで
@Provides @Singleton
public SpellChecker provideSpellChecker(){
String dbUrl = "jdbc:mysql://localhost:5326/emp";
String user = "user";
int timeout = 100;
SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
return SpellChecker;
}
例
クラスレベルでのスコープの動作を見てみましょう。
@Singletonアノテーションを使用した結果
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
SpellChecker spellChecker = new SpellCheckerImpl();
injector.injectMembers(spellChecker);
TextEditor editor = injector.getInstance(TextEditor.class);
System.out.println(editor.getSpellCheckerId());
TextEditor editor1 = injector.getInstance(TextEditor.class);
System.out.println(editor1.getSpellCheckerId());
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public void setSpellChecker(SpellChecker spellChecker){
this.spellChecker = spellChecker;
}
public TextEditor() { }
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
public double getSpellCheckerId(){
return spellChecker.getId();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(SpellChecker.class).to(SpellCheckerImpl.class);
}
}
interface SpellChecker {
public double getId();
public void checkSpelling();
}
@Singleton
class SpellCheckerImpl implements SpellChecker {
double id;
public SpellCheckerImpl(){
id = Math.random();
}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
@Override
public double getId() {
return id;
}
}
ファイルをコンパイルして実行すると、次の出力が表示される場合があります。
0.3055839187063575
0.3055839187063575
@Singletonアノテーションなしの結果
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
SpellChecker spellChecker = new SpellCheckerImpl();
injector.injectMembers(spellChecker);
TextEditor editor = injector.getInstance(TextEditor.class);
System.out.println(editor.getSpellCheckerId());
TextEditor editor1 = injector.getInstance(TextEditor.class);
System.out.println(editor1.getSpellCheckerId());
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public void setSpellChecker(SpellChecker spellChecker){
this.spellChecker = spellChecker;
}
public TextEditor() { }
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
public double getSpellCheckerId(){
return spellChecker.getId();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(SpellChecker.class).to(SpellCheckerImpl.class);
}
}
interface SpellChecker {
public double getId();
public void checkSpelling();
}
class SpellCheckerImpl implements SpellChecker {
double id;
public SpellCheckerImpl(){
id = Math.random();
}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
@Override
public double getId() {
return id;
}
}
ファイルをコンパイルして実行すると、次の出力が表示される場合があります。
0.556007079571739
0.22095011760351602
Google Guice-AOP
AOP、アスペクト指向プログラミングでは、プログラムロジックをいわゆる懸念事項と呼ばれる別個の部分に分解する必要があります。アプリケーションの複数のポイントにまたがる機能は横断的関心事と呼ばれ、これらの横断的関心事は概念的にアプリケーションのビジネスロジックから分離されています。ロギング、監査、宣言型トランザクション、セキュリティ、キャッシングなどの側面のさまざまな一般的な良い例があります。
OOPのモジュール性の主要な単位はクラスですが、AOPのモジュール性の単位はアスペクトです。依存性注入は、アプリケーションオブジェクトを相互に分離するのに役立ち、AOPは、横断的関心事をそれらが影響するオブジェクトから分離するのに役立ちます。AOPは、Perl、.NET、Javaなどのプログラミング言語のトリガーのようなものです。Guiceは、アプリケーションをインターセプトするためのインターセプターを提供します。たとえば、メソッドが実行されるときに、メソッドの実行の前後に機能を追加できます。
重要なクラス
Matcher-マッチャーは、値を受け入れるか拒否するためのインターフェースです。Guice AOPでは、2つのマッチャーが必要です。1つは参加するクラスを定義するためのもので、もう1つはそれらのクラスのメソッド用です。
MethodInterceptor-MethodInterceptorsは、マッチングメソッドが呼び出されたときに実行されます。彼らは呼び出しを検査することができます:メソッド、その引数、および受信インスタンス。横断的なロジックを実行してから、基礎となるメソッドに委任することができます。最後に、戻り値または例外を検査して返す場合があります。
例
GuiceTesterという名前のJavaクラスを作成します。
GuiceTester.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.matcher.Matchers;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(SpellChecker.class).to(SpellCheckerImpl.class);
bindInterceptor(Matchers.any(),
Matchers.annotatedWith(CallTracker.class),
new CallTrackerService());
}
}
//spell checker interface
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
@Override @CallTracker
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD)
@interface CallTracker {}
class CallTrackerService implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("Before " + invocation.getMethod().getName());
Object result = invocation.proceed();
System.out.println("After " + invocation.getMethod().getName());
return result;
}
}
ファイルをコンパイルして実行すると、次の出力が表示される場合があります。
Before checkSpelling
Inside checkSpelling.
After checkSpelling