Java Naming and Directory Interface(以降、JNDI)は、各種ネーミングサービスおよびディレクトリサービスに標準のAPIを使用してアクセスすることを可能とします。JNDIアーキテクチャは、API(Application Programming Interface)およびSPI(Service Provider Interface)で構成されます。
本製品では、Interstage Java EE 6 DASサービスの各種オブジェクトにアクセスするJNDI SPIの実装を提供しており、この実装をJNDIサービスプロバイダと呼びます。これにより、Java EEコンポーネントはJNDI APIを使用してJNDIサービスプロバイダが提供する各種オブジェクトにアクセスできます。
以下にJNDIの構成を記載します。以下の図に記載されているNamingManagerとは、指定された環境プロパティを元にJNDI SPIを実装するJNDIサービスプロバイダを呼び出し、指定された名前のオブジェクトを返却・管理するクラスです。API、NamingManager、SPIは共にJava SEから提供されます。
以下について説明します。
Dependency Injectionの利用について
Java EE以降では、JNDIと同様にコンテナが管理するオブジェクトにアクセスする方法として、Dependency Injection(以降、DI)という新たな方法が提供されています。JNDIを使用する場合には、アプリケーションサーバが管理するオブジェクトをJava EEコンポーネントがlookupメソッドを実行して取得する必要があります。しかし、DIを使用した場合には、Java EEコンポーネントにアノテーションを定義していれば、定義したアノテーションをコンテナが動的に読み込んで、必要に応じてオブジェクトの情報を注入します。DIを使用すると以下の利点があります。
注意
コンテナは、Java EEコンポーネントのインスタンス生成時に対象のオブジェクトを取得してアノテーションに注入します。インスタンス生成後はオブジェクトの再注入は行いませんので、オブジェクトを削除すると利用できなくなります。特にStateful Session Beanの注入は、Stateful Session Beanインスタンスの無通信時間監視機能によってインスタンスが削除される可能性があるため、推奨しません。
JNDIを利用した場合、参照先のアプリケーションサーバの環境が構築されている必要がありますが、DIを使用した場合には、通常のアプリケーションとして動作させることもできるため、単体テストが可能です。
DIを使用するとコンテナが動的にアノテーションを読み込んで必要に応じてオブジェクトを注入するため、アプリケーションのコード量が削減されます。また、従来のJava EEコンポーネントでは、アプリケーションの動作をXMLファイルに定義する必要がありましたが、DIを使用するとアプリケーションの動作をアノテーションとして定義できるため、XMLファイルの記述量が削減されます。
上記のようにDIを使用することで、アプリケーションの開発効率が向上します。DIの使用については、各Java EE規約を参照してください。従来通りにJNDIを使用することも可能です。
ネーミングサービスと環境ネーミングコンテキスト
Java EEのJNDIはオブジェクトを管理する仕組みとして、以下の2つを提供します。
Interstage Java EE 6 DASサービス上のオブジェクトを一意のJNDI名で管理するネーミングサービスです。
Java EEコンポーネントのdeployment descriptorファイルの定義内容を元に、Java EEコンポーネントごとにjava:comp/env環境ネーミングコンテキストでオブジェクトを管理するネーミングコンテキストです。
アプリケーションの汎用性が向上するため、環境ネーミングコンテキストの利用をお勧めします。
それぞれの特徴については、「3.8.1 ネーミングサービス」と「3.8.2 環境ネーミングコンテキスト(Environment Naming Context)」を参照してください。また、仕様の違いについては、「3.8.3 ネーミングサービスと環境ネーミングコンテキストの仕様差異」を参照してください。
オブジェクトの階層管理
JNDIサービスプロバイダは、オブジェクトを階層管理します。例えば、「jdbc/MyDS」というJNDI名でオブジェクトを登録した場合、「jdbc」の部分をサブコンテキストと呼び、サブコンテキスト内で「MyDS」という名前のオブジェクトを管理します。「jdbc/MyCmp/MyDS」などのように複数階層のサブコンテキストを持つこともできます。
JNDI名は、サブコンテキスト内で一意となる必要があります。また、JNDI名が別名であってもサブコンテキストの名前と、実際のオブジェクトの名前が重複するとオブジェクトの登録に失敗します。
アプリケーションでオブジェクトを参照する場合、一般的にはJNDI名を指定してオブジェクトの参照を取得します。別の参照方法として、上記のようにオブジェクトが階層管理されているため、サブコンテキストから段階的にオブジェクトを参照することもできます。例えばJNDI名が「jdbc/MyDS」の場合、JNDI APIのlookupメソッドを実行して「jdbc」という名前でサブコンテキスト(javax.naming.Contextオブジェクト)を取得し、そのサブコンテキストに対して「MyDS」という名前でlookupメソッドを実行しても登録されたオブジェクトを取得できます。