JNDI (Java Naming and Directory Interface)

JNDI (Java Naming and Directory Interface)とは、ネーミング・サービスおよびディレクトリー・サービスを扱うためのインタフェースです。

ネーミング・サービスとは、名前をオブジェクトに関連付けたり、名前を基に関連付けられたオブジェクトを検索することのできるサービスです。

ディレクトリー・サービスとは、ネーミング・サービスを拡張したものです。ネーミング・サービスと同様に、関連付けられたオブジェクトを検索することに加えて、オブジェクトの属性を扱うこともできます。

ネーミング・サービスやディレクトリー・サービスを提供するサービス・プロバイダには、次のようなものがあります。

これらのサービス・プロバイダにアクセスするためのインタフェースがJNDIです。

ネーミング・サービスにアクセスするには、javax.namingパッケージを使用します。

パッケージのインポート

javax.namingパッケージは、ネーミング・サービスにアクセスするためのクラスやインタフェースを提供します。ネーミング・サービスにアクセスするJavaアプリケーションは、javax.namingパッケージをインポートする必要があります。

import javax.naming.*;

データソース

JNDIにおけるデータソース(DataSource)とは、データベース接続に関する情報と接続プールを管理するJavaオブジェクトのことです。データソースは、アプリケーションがデータベースにアクセスするための標準的かつ抽象化された手段を提供します。

接続方法の違い
JNDIデータソース 直接接続
クラス DataSource DriverManager
接続管理 接続プールを自動管理(高性能) 要求ごとに接続を作成・切断(低性能)
設定場所 アプリケーションサーバーの設定ファイル アプリケーションコード内
セキュリティ 接続情報がコードから隠蔽され、安全 接続情報がコード内に露出する可能性がある

JNDIデータソースの主な役割と、それを利用するメリットは以下の通りです。

接続情報の抽象化

JNDIのデータソースは、アプリケーションコードからデータベースのURL、ユーザー名およびパスワードなどの具体的な接続情報を分離します。

アプリケーションは、jdbc/MyDb といったJNDI名を使ってデータソースオブジェクトを取得するだけで済みます。実際の接続情報は、アプリケーションサーバー(Tomcatなど)の設定ファイル内で管理されます。

接続プールの提供

データソースオブジェクトは通常、データベース接続プールを内部で管理します。接続プールにより、アプリケーションがデータベースにアクセスするたびに新しい接続を作成・切断するオーバーヘッドがなくなります。これにより、アプリケーションのパフォーマンスが大幅に向上し、多数のユーザーからの要求にも効率的に対応できます。

移植性の向上

データベースの種類や設定が変更されても、アプリケーションコードを変更する必要がありません。アプリケーションサーバーの設定ファイル内のデータソース情報だけを変更すれば、コードはそのまま動作します。

javax.namingパッケージがスローする例外

javax.namingパッケージのメソッドは、javax.naming.NamingException例外をスローすることがあります。したがって、JDBCパッケージのメソッドを呼び出す箇所では、これをキャッチまたはスロー宣言する必要があります。

javax.naming.NamingException例外をキャッチする例を次に示します。

try {
  // javax.namingパッケージのメソッド呼び出し
} catch (NamingException e) {
  // 例外処理
}

javax.naming.NamingException例外をスロー宣言する例を次に示します。

public class void main(String args[]) throws NamingException {
  // javax.namingパッケージのメソッド
}

Contextインタフェース

Contextインタフェースは、バインディング(名前とオブジェクトの関連付け)のセットから構成されるネーミング・コンテキストを表しています。

初期コンテキストを作成するJavaソースコードの例を次に示します。

Context context = new InitialContext();

ネームド・オブジェクトの検索

名前を基に、関連付けられたオブジェクト(ネームド・オブジェクト)を検索するには、Context.lookup()メソッドを使用します。

Object lookup(String name) throws NamingException
Object lookup(Name name) throws NamingException