レベルエンター山本大のブログ

面白いプログラミング教育を若い人たちに

BLOCKVROCKリファレンス目次はこちら

[翻訳]Guice User's Guide ■21. Example: Integrating With JNDI

サンプル:JNDIを使った統合

Say for example we want to bind to objects from JNDI. We could implement a reusable custom provider similar to the one below. Notice we inject the JNDI Context:

たとえばJNDIに登録されたオブジェクトをバインドしたい時、以下のような再利用可能なカスタムプロバイダーを実装します。JNDIコンテキストをインジェクトしていることに注目してください。

package mypackage;

import com.google.inject.*;
import javax.naming.*;

class JndiProvider<T> implements Provider<T> {

  @Inject Context context;
  final String name;
  final Class<T> type;

  JndiProvider(Class<T> type, String name) {
    this.name = name;
    this.type = type;
  }

  public T get() {
    try {
      return type.cast(context.lookup(name));
    }
    catch (NamingException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * Creates a JNDI provider for the given
   * type and name.
   */
  static <T> Provider<T> fromJndi(
      Class<T> type, String name) {
    return new JndiProvider<T>(type, name);
  }
}

Thanks to generic type erasure, we must pass in the class at runtime. You could skip this step, but tracking down type casting errors later might be a little tricky (i.e. if JNDI returns an object of the wrong type).

Genericタイプが消えてしてしまうせいで、実行時にクラスに取得したオブジェクトをキャストしなくてはなりません。このステップは省略可能です。しかし、タイプキャストのエラーを後から突きとめることは、少しトリッキーな処理が必要になります。(たとえば、JNDIが間違った型を返したときなど)

We can use our custom JndiProvider to bind DataSource to an object from JNDI:

こんなときは、JNDIから取得したオブジェクトをDataSourceクラスにバインドするカスタムJndiProviderクラスを使いましょう。

import com.google.inject.*;
import static mypackage.JndiProvider.fromJndi;
import javax.naming.*;
import javax.sql.DataSource;

...

// Bind Context to the default InitialContext.
bind(Context.class).to(InitialContext.class);

// Bind to DataSource from JNDI.
bind(DataSource.class)
    .toProvider(fromJndi(DataSource.class, "..."));