Upload page content

You can upload content for the page named below. If you change the page name, you can also upload content for another page. If the page name is empty, we derive the page name from the file name.

File to load page content from
Page name
Comment

Locked History Actions

guice/Manual/Integration/CustomInjections

カスタムインジェクション

標準的な@Injectによる注入のほか、Guiceはカスタム注入のためのフックを提供している。 これにより、それ自身のセマンティックスやアノテーションを持つ他のフレームワークのホストをGuiceとすることができる。 多くの開発者は直接的にカスタム注入を使うことはないだろうが、(訳注:Guiceの?)エクステンションやサードパーティライブラリでこれらを目にすることがあるかもしれない。 それぞれのカスタム注入についてはそれぞれタイプリスナ、インジェクションリスナと登録が必要である。

Guiceが注入を行うとき、TypeListenerはその型を通知される。 一つの型について一度だけ通知されるので、その型のメンバーを列挙するなどの特に多い操作を行うのにもっとも適切である。 With their inspection complete, type listeners may register instance listeners for values as they're injected.

MembersInjectorsInjectionListenersはGuiceがインスタンスへの注入を行った後でコールバックを受け取ることに使用できる。 インスタンスは最初にGuiceの注入を受け、次にカスタムメンバーインジェクタによる注入を受け、最後にインジェクションリスナに通知される。 それらはインスタンスごとに通知されるため、その実行はできるだけ素早く行う必要がある。

例:Log4Jロガーに注入する

Guiceはjava.util.Loggerインスタンスに注入するビルトインサポートがあり、それらは注入を受けるインスタンスの型の名称が使われる。 タイプリスナAPIを使うことによりorg.apache.log4j.Loggerに対して同様のhigh-fidelityネーミングを行うことができる。 このフォーマットのフィールドに注入してみよう。

import org.apache.log4j.Logger;
import com.publicobject.log4j.InjectLogger;

public class PaymentService {
  @InjectLogger Logger logger;

  ...
}

モジュールにてカスタムタイプリスナLog4JTypeListenerをまず登録する。 matcherを使って、どのタイプをリッスンするかを選択する。

  @Override protected void configure() {
    bindListener(Matchers.any(), new Log4JTypeListener());
  }

TypeListenerにて型のフィールドをスキャンして、Log4Jロガーを探す。 見つかったロガーフィールドそれぞれについて渡されたTypeEncounterにLog4JMembersInjectorを登録する。

  class Log4JTypeListener implements TypeListener {
    public <T> void hear(TypeLiteral<T> typeLiteral, TypeEncounter<T> typeEncounter) {
      for (Field field : typeLiteral.getRawType().getDeclaredFields()) {
        if (field.getType() == Logger.class
            && field.isAnnotationPresent(InjectLogger.class)) {
          typeEncounter.register(new Log4JMembersInjector<T>(field));
        }
      }
    }
  }

最後にLog4JMembersInjectorをロガーをセットするように実装する。 この例では、フィールドに同じインスタンスをセットするようにしている。 実際のアプリケーションでは、値を導出するか、プロバイダにリクエストするようにする。

  class Log4JMembersInjector<T> implements MembersInjector<T> {
    private final Field field;
    private final Logger logger;

    Log4JMembersInjector(Field field) {
      this.field = field;
      this.logger = Logger.getLogger(field.getDeclaringClass());
      field.setAccessible(true);
    }

    public void injectMembers(T t) {
      try {
        field.set(t, logger);
      } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
      }
    }
  }