JNDI在java程式,特別是J2EE的程式中,是一個很重要 的技術,甚至可以當作是從J2SE-->J2EE的一個蠻重要的轉捩點。 如果要以一句話對JNDI下個定義的話,小弟以為,可以說是 "對環境中資源命名,以及從此命名取得該資源"的一項技術。 像這樣的"命名"服務,在網路中是很常見的,像Active Directory、 LDAP、DNS都是類似的服務,JNDI所提供的是將這些服務抽象化, 讓我們可以透過API-->provider-->service的方式來取得各個服務。 這樣的做法在J2EE中很常用,不論是EJB、DataSource、JDO,都 可以這樣來達到所謂的location transparency. 接著我們就來簡單的介紹 一下JNDI API的使用方式。 在開始使用JNDI API之前,我們必須先取得所謂的Context,亦即 現在所使用的provider以及環境參數,通常我們可以這樣來取得Context: Hashtable env=new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.fscontext.RefFSContextFactory"); env.put(Context.PROVIDER_URL ,"file:."); Context context=new InitialContext(env); 我們在Hashtable裡面置入的參數分別代表provider的class name以及provider 的url,這兩個變數的設定值會在各個provider的文件裡面有說明。當我們 要存取物件的時候,使用下列方法: context.rebind(name,object); context.lookup(name); 然而,並不是所有的object都可以順利的rebind,通常,provider會限制只有 Serializable、Referenceable或是Reference object可以被rebind。Serializable的儲存 一般都能了解,但是Referenceable呢?實際上,因為不是所有的物件都能夠 被Serializable,因此Referenceable和Reference可以說是間接的方法,在這個方法中, 我們存進去的並不是物件本身,而是物件的一些參數,並且會設定該物件之後 可以使用哪個產生器(ObjectFactory)來根據這些參數產生。因此,使用這個方法 我們還必須自己撰寫ObjectFactory,並且在ObjectFactory中讀取之前儲存的參數, 並且產生物件,然後將物件傳回。 接著我們來看一個例子: -------------------------------------------------------------------------------------------------- import javax.naming.*; public class referenceableobject implements Referenceable { public String value=""; public Reference getReference() throws NamingException { return new Reference(referenceableobject.class.getName(), new StringRefAddr("value",value), ReferenceableObjectFactory.class.getName(), null ); } } ------------------------------------------------------------------------------------------------- 上列是一個Referenceable物件 ------------------------------------------------------------------------------------------------- import javax.naming.*; import javax.naming.spi.*; import java.util.*; public class ReferenceableObjectFactory implements ObjectFactory { public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception { Reference ref=(Reference)obj; String value=(String)(ref.get("value").getContent()); referenceableobject obj1=new referenceableobject(); obj1.value=value; return obj1; } } ------------------------------------------------------------------------------------------------- 上列則是該Referenceable物件的ObjectFactory ------------------------------------------------------------------------------------------------- Context context=new InitialContext(env); ------------------------------------------------------------------------------------------------- import java.util.*; import javax.naming.*; import java.io.*; public class test { public static void main(String args[]) throws Exception { Properties prop=System.getProperties(); Properties newenv=new Properties(prop); newenv.setProperty(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.fscontext.RefFSContextFactory"); newenv.setProperty(Context.PROVIDER_URL ,"file:."); System.setProperties(newenv); Context context=new InitialContext(); referenceableobject obj1=new referenceableobject(); obj1.value="this is a test."; context.rebind("referenceable1",obj1); referenceableobject obj2=(referenceableobject)(context.lookup("referenceable1")); System.out.println(obj2.value); } } ------------------------------------------------------------------------------------------------- 上列則是主程式的部分。