優點
包含了大量的命名和
目錄服務,使用通用接口來訪問不同種類的服務;
建立起邏輯關聯,允許把名稱同Java
對象或資源關聯起來,而不必知道對象或資源的物理ID。
JNDI程式包:
利用JNDI的命名與服務功能來滿足企業級API對命名與服務的訪問,諸如EJB、JMS、JDBC 2.0以及IIOP上的RMI通過JNDI來使用CORBA的命名服務。
架構
JNDI架構提供了一組標準的獨立於命名系統的
API,這些API構建在與命名系統有關的驅動之上。這一層有助於將套用與實際數據源分離,因此不管套用訪問的是
LDAP、
RMI、
DNS、還是其他的
目錄服務。換句話說,JNDI獨立於
目錄服務的具體實現,只要有目錄的服務提供接口(或驅動),就可以使用目錄。
關於JNDI要注意的重要一點是,它提供了套用
編程接口(application programming interface,API)和服務提供者接口(service provider interface,SPI)。這一點的真正含義是,要讓套用與命名服務或
目錄服務互動,必須有這個服務的JNDI服務提供者,這正是JNDI SPI發揮作用的地方。服務提供者基本上是一組類,這些類為各種具體的命名和
目錄服務實現了JNDI接口—很像JDBC驅動為各種具體的
資料庫系統實現了JDBC接口一樣。作為一個套用開發者,我們不必操心JNDI SPI的具體實現。只需要確認要使用的每一個命名或
目錄服務都有服務提供者。
組件
1、Javax.naming:包含了訪問命名服務的類和接口。例如,它定義了Context接口,這是命名服務執行查詢的入口。
2、Javax.naming.directory:對命名包的擴充,提供了訪問
目錄服務的類和接口。例如,它為屬性增加了新的類,提供了表示目錄上下文的DirContext接口,定義了檢查和更新目錄
對象的屬性的方法。
3、Javax.naming.event:提供了對訪問命名和
目錄服務時的事件通知的支持。例如,定義了NamingEvent類,這個類用來表示命名/
目錄服務產生的事件,定義了偵聽NamingEvents的NamingListener接口。
5、Javax.naming.spi:這個包提供了一個方法,通過
javax.naming和有關包動態增加對訪問命名和
目錄服務的支持。這個包是為有興趣創建服務提供者的開發者提供的。
用途
命名或
目錄服務使用戶可以
集中存儲共有信息,這一點在網路套用中是重要的,因為這使得這樣的套用更協調、更容易管理。例如,可以將印表機設定存儲在
目錄服務中,以便被與印表機有關的套用使用。
我們大家每天都不知不覺地使用了命名服務。命名系統中的
對象可以是
DNS記錄中的名稱、
套用伺服器中的EJB組件(Enterprise JavaBeans Component)、
LDAP(Lightweight Directory Access Protocol)中的用戶Profile。
目錄服務是命名服務的自然擴展。兩者之間的關鍵差別是
目錄服務中
對象可以有屬性(例如,用戶有email地址),而命名服務中對象沒有屬性。因此,在
目錄服務中,你可以根據屬性搜尋
對象。JNDI允許你訪問檔案系統中的檔案,定位遠程RMI註冊的
對象,訪問像LDAP這樣的
目錄服務,定位網路上的EJB組件。
對於象LDAP
客戶端、套用
launcher、類瀏覽器、網路管理實用程式,甚至地址薄這樣的套用來說,JNDI是一個很好的選擇。
組成部分
JNDI提供了一種統一的方式,可以用在網路上查找和訪問服務。通過指定一個資源名稱,該名稱對應於
資料庫或命名服務中的一個記錄,同時返回資料庫連線建立所必須的信息。
代碼示例:
try{
Context cntxt = new InitialContext();
DataSource ds = (DataSource) cntxt.lookup("jdbc/dpt");
}
catch(NamingException ne){
...
}
技術套用
代碼示例:
try{
Properties env = new Properties();
InitialContext inictxt = new InitialContext(env);
TopicConnectionFactory connFactory = (TopicConnectionFactory) inictxt.lookup("TTopicConnectionFactory");
...
}
catch(NamingException ne){
...
}
訪問特定目錄:舉個例子,人是個
對象,他有好幾個屬性,諸如這個人的姓名、電話號碼、
電子郵件地址、郵政編碼等屬性。通過getAttributes()方法
Attribute attr = directory.getAttributes(personName).get("email");
String email = (String)attr.get();
通過使用JNDI讓客戶使用
對象的名稱或屬性來查找對象:
foxes = directory.search("o=Wiz,c=US", "sn=Fox", controls);
通過使用JNDI來查找諸如印表機、
資料庫這樣的
對象,查找印表機的例子:
Printer printer = (Printer)namespace.lookup(printerName);
printer.print(document);
瀏覽命名空間:
NamingEnumeration list = namespace.list("o=Widget, c=US");
while (list.hasMore()) {
NameClassPair entry = (NameClassPair)list.next();
display(entry.getName(), entry.getClassName());
}
常用操作
void bind(String sName,Object object);――綁定:把名稱同
對象關聯的過程
void rebind(String sName,Object object);――重新綁定:用來把
對象同一個已經存在的名稱重新綁定
void unbind(String sName);――釋放:用來把
對象從目錄中釋放出來
Object lookup(String sName);――查找:返回目錄中的一個
對象
void rename(String sOldName,String sNewName);――
重命名:用來修改
對象名稱綁定的名稱
NamingEnumeration listBinding(String sName);――清單:返回綁定在特定上下文中
對象的清單列表
NamingEnumeration list(String sName);
NamingEnumeration namEnumList = ctxt.listBinding("cntxtName");
...
while ( namEnumList.hasMore() ) {
Binding bnd = (Binding) namEnumList.next();
String sObjName = bnd.getName();
String sClassName = bnd.getClassName();
SomeObject objLocal = (SomeObject) bnd.getObject();
}