JNDI (The Java Naming and Directory Interface,Java 命名和目錄接口) 是一組在Java 應(yīng)用中訪問(wèn)命名和目錄服務(wù)的API。為開(kāi)發(fā)人員提供了查找和訪問(wèn)各種命名和目錄服務(wù)的通用、統(tǒng)一的方式。借助于JNDI 提供的接口,能夠通過(guò)名字定位用戶(hù)、機(jī)器、網(wǎng)絡(luò)、對(duì)象服務(wù)等。
命名服務(wù):就像DNS一樣,通過(guò)命名服務(wù)器提供服務(wù),大部分的J2EE 服務(wù)器都含有命名服務(wù)器。
目錄服務(wù):一種簡(jiǎn)化的RDBMS 系統(tǒng),通過(guò)目錄具有的屬性保存一些簡(jiǎn)單的信息。目錄服務(wù)通過(guò)目錄服務(wù)器實(shí)現(xiàn),比如微軟ACTIVE DIRECTORY 等。
JNDI 的好處:
(1)包含大量命名和目錄服務(wù),可以使用相同API 調(diào)用訪問(wèn)任何命名或目錄服務(wù)。
(2)可以同時(shí)連接多個(gè)命名和目錄服務(wù)。
(3)允許把名稱(chēng)同JAVA 對(duì)象或資源關(guān)聯(lián)起來(lái),不必知道對(duì)象或資源的物理ID。
(4)使用通用接口訪問(wèn)不同種類(lèi)的目錄服務(wù)
(5)使得開(kāi)發(fā)人員能夠集中使用和實(shí)現(xiàn)一種類(lèi)型的命名或目錄服務(wù)客戶(hù)API 上。
上下文:由0 或多個(gè)綁定構(gòu)成。比如java/MySql,java 為上下文(context),MySql 為命名
子上下文(subConext):上下文下的上下文。比如MyJNDITree/ejb/helloBean,ejb 為子上下文。
因?yàn)?/span>JNDI 是一組接口,所以我們只需根據(jù)接口規(guī)范編程就可以。要通過(guò)JNDI 進(jìn)行資源訪問(wèn),我們必須設(shè)置初始化上下文的參數(shù),主要是設(shè)置JNDI 驅(qū)動(dòng)的類(lèi)名(java.naming.factory.initial) 和提供命名服務(wù)的URL (java.naming.provider.url)。
因?yàn)?/span>Jndi 的實(shí)現(xiàn)產(chǎn)品有很多。所以java.naming.factory.initial 的值因提供JNDI 服務(wù)器的不同而不同,java.naming.provider.url 的值包括提供命名服務(wù)的主機(jī)地址和端口號(hào)。
訪問(wèn)Jboss 服務(wù)器的例子代碼:
Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url", "localhost:1099");
InitialContext = new InitialContext(props);
HelloWorld helloworld = (HelloWorld) ctx.lookup("HelloWorldBean/remote");

訪問(wèn)Sun 應(yīng)用服務(wù)器的例子代碼:
Properties props = new Properties();
props.setProperty("java.naming.factory.initial",
"com.sun.enterprise.naming.SerialInitContextFactory");
props.setProperty("java.naming.provider.url", "localhost:3700");
InitialContext = new InitialContext(props);
HelloWorld helloworld = (HelloWorld) ctx.lookup("com.foshanshop.ejb3.HelloWorld");

訪問(wèn)Weblogic10 應(yīng)用服務(wù)器的例子代碼:
Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory");
props.setProperty("java.naming.provider.url", "t3://localhost:7001");
InitialContext = new InitialContext(props);
HelloWorld helloworld = (HelloWorld) ctx.lookup("HelloWorldBean#com.foshanshop.ejb3.HelloWorld");
JBOSS 環(huán)境下JNDI 樹(shù)的命名約定:
(1)java:copm 這個(gè)上下文環(huán)境和其子上下文環(huán)境僅能被與之相關(guān)的特定應(yīng)用組件訪問(wèn)和使用
(2)java: 子上下文環(huán)境和綁定的對(duì)象只能被Jboss 服務(wù)器虛擬機(jī)內(nèi)的應(yīng)用訪問(wèn)
(3)其他上下文環(huán)境 只要實(shí)現(xiàn)序列化就可以被遠(yuǎn)程用戶(hù)調(diào)用。
當(dāng)你把EJB發(fā)布到JBOSS后,你就可以在jboss 的管理平臺(tái)查看她們的JNDI 名,輸入下面URL http://localhost:8080/jmx-console/,點(diǎn)擊“service=JNDIView” link,在出現(xiàn)的page里找到“List of MBean operations:”欄的“list()”方法,click “Invoke”button,就會(huì)看到下面的界面
在上圖中可以看見(jiàn)HelloWorld 會(huì)話(huà)Bean 的JNDI路徑,JNDI 路徑名的組成規(guī)則是“上層名稱(chēng)/下層名稱(chēng),每層之間以”/”分隔。HelloWorld 會(huì)話(huà)Bean 的JNDI路徑名是:HelloWorldBean/remote
下面要重點(diǎn)說(shuō)明一下Jboss EJB JNDI 名稱(chēng)默認(rèn)的命名規(guī)則,命名規(guī)則如下:
1> 如果EJB 打包進(jìn)后綴為*.ear 的J2EE 發(fā)布文件,默認(rèn)的JNDI 路徑名稱(chēng)是
訪問(wèn)本地接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local
訪問(wèn)遠(yuǎn)程接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/remote
例:EJB HelloWorld 打包進(jìn)名為 HelloWorld.ear 的J2EE 應(yīng)用,訪問(wèn)她遠(yuǎn)程接口的JNDI 名是:HelloWorld/HelloWorldBean/remote
2> 如果EJB 應(yīng)用打包成后綴為*.jar 的發(fā)布文件, 默認(rèn)的JNDI 路徑名稱(chēng)是
訪問(wèn)本地接口:EJB-CLASS-NAME/local
訪問(wèn)遠(yuǎn)程接口:EJB-CLASS-NAME/remote
例: HelloWorld 應(yīng)用打包成HelloWorld.jar 文件,訪問(wèn)她遠(yuǎn)程接口的JNDI 名稱(chēng)是:HelloWorldBean/remote
注意:EJB-CLASS-NAME 是不帶包名的,如com.foshanshop.ejb3.impl.HelloWorldBean 只需取HelloWorldBean。
目前網(wǎng)上很多教材獲取JNDI 路徑名的方式不適用在jboss 下,如:
HelloWorld helloworld = (HelloWorld) ctx.lookup(HelloWorld.class.getName());
這種方式適用于Sun Application Server 及glassfish
自定義JNDI 命名
默認(rèn)的JNDI 命名規(guī)則上面已經(jīng)介紹過(guò),但有些情況下需要自定義名稱(chēng)。在Jboss 中要自定義JNDI 名稱(chēng),可以使用@LocalBinding 和@RemoteBinding 注釋
關(guān)鍵代碼(只需要在bean interface前加binding注釋):
import org.jboss.annotation.ejb.RemoteBinding;
...
@Remote
@RemoteBinding (jndiBinding="testbinding/myAccount")

publicinterface MyAccount extends Serializable
{
publicint Add(int a, int b);
publicint getResult() ;
}
那么在client端調(diào)用上面的EJB的代碼為:
InitialContext ctx = new InitialContext(props);
MyAccount bean1 = (MyAccount) ctx.lookup("testbinding/myAccount");

posted on 2007-07-20 14:50
冰封的愛(ài) 閱讀(3942)
評(píng)論(2) 編輯 收藏 所屬分類(lèi):
J2EE